PTA_L2题解集

前言:L2部分我感觉更侧重于算法基础或者思维,L1部分偏语法。L2一些数据结构课本题我都不写了,没意思。

L2-001 紧急救援

题解:因为没有负边权,所以我使用的是最优化的优先队列dijkstra算法。设num[i]表示到达i点最短路的路径数量,sum[i]表示到达i点最短路的时候的最大权值和。当d[v]>d[u]+edge[i].w时,更新d[v]值,同时num[v]=num[u] . sum[v]=sum[u]+a[v]。如果d[v]=d[u]+edge[i].w时,需要更新的是num[v]的数量,即num[v]+=num[u],同时可以更新sum的情况,if(sum[v]<sum[u]+a[v]) sum[v]=sum[u]+a[v];具体看代码

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define white 0
#define grey 1
#define black 2
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=3e5+5;
int tot,head[maxn];
struct E{
    int to,next,w;
}edge[maxn<<1];
void add(int u,int v,int w){
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n,m,S,T;
int a[maxn],d[maxn],color[maxn],pre[maxn];
int num[maxn],sum[maxn];
priority_queue<pair<int,int> >q;
void dijkstra(int s){
    for(int i=1;i<=n;i++) color[i]=white,d[i]=INF,pre[i]=s;
    q.push({0,s});d[s]=0;color[s]=grey;
    num[s]=1;sum[s]=a[s];pre[s]=0;
    while(!q.empty()){
        pair<int,int> f=q.top();q.pop();
        int u=f.second;
        color[u]=black;
        if(d[u]<(-1)*f.first) continue;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(color[v]==black) continue;
            if(d[v]>d[u]+edge[i].w){
                d[v]=d[u]+edge[i].w;
                pre[v]=u;
                num[v]=num[u];
                sum[v]=sum[u]+a[v];
                color[v]=grey;
                q.push({(-1)*d[v],v});
            }
            else if(d[v]==d[u]+edge[i].w){
                num[v]+=num[u];
                if(sum[v]<sum[u]+a[v]){
                    sum[v]=sum[u]+a[v];
                    pre[v]=u;
                }
            }
        }
    }    
}
stack<int> s;
void get_path(int t){
    while(t){
        s.push(t-1);
        t=pre[t];
    }
}
int main(){
    scanf("%d%d%d%d",&n,&m,&S,&T);mem(head,-1);
    ++S;++T;
    rep(i,1,n) scanf("%d",&a[i]);
    rep(i,1,m){
        int u,v,w;scanf("%d%d%d",&u,&v,&w);
        ++u;++v;
        add(u,v,w);add(v,u,w);
    }
    dijkstra(S);
    cout<<num[T]<<" "<<sum[T]<<endl;
    get_path(T);
    while(!s.empty()){
        int cur=s.top();s.pop();
        if(s.size()) cout<<cur<<" ";
        else cout<<cur;
    }
}
View Code

 L2-002 链表去重

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
struct Node{
    int address,key,next,num;
}node[maxn];
bool vis[maxn];
bool cmp(Node a,Node b){
    return a.num<b.num;
}
int main(){
    int head,n;scanf("%d%d",&head,&n);
    for(int i=0;i<maxn;i++) node[i].num=INF;
    for(int i=0;i<n;i++){
        int a;scanf("%d",&a);
        scanf("%d%d",&node[a].key,&node[a].next);
        node[a].address=a;        
    } 
    int k1=0,k2=0;
    for(int i=head;i!=-1;i=node[i].next){
        if(!vis[abs(node[i].key)]){
            vis[abs(node[i].key)]=true;
            node[i].num=k1++;
        }else{
            node[i].num=maxn+k2;
            k2++;
        }
    }
    sort(node,node+maxn,cmp);
    int k=k1+k2;
    for(int i=0;i<k;i++){
        if(i!=k1-1&&i!=k-1){
            printf("%05d %d %05d
",node[i].address,node[i].key,node[i+1].address);
        }else{
            printf("%05d %d -1
",node[i].address,node[i].key);
        }
    }
}
View Code

L2-003 月饼

坑点:注意正数与正整数的区别,用double输入比较安全

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
double w[maxn],p[maxn];double s[maxn];
struct Node{
    double s,t;
}node[maxn];
bool cmp(Node a,Node b){
    return a.s>b.s;
}
int main(){
    int n,weight;scanf("%d%d",&n,&weight);
    rep(i,1,n) scanf("%lf",&w[i]);
    rep(i,1,n) scanf("%lf",&p[i]);
    rep(i,1,n){
        node[i].s=1.00*p[i]/w[i];
        node[i].t=w[i];
    }
    sort(node+1,node+n+1,cmp);
    double ans=0;
    rep(i,1,n){
        if(weight>=node[i].t){
            weight-=node[i].t;
            ans+=node[i].t*node[i].s;
        }else{
            ans+=weight*node[i].s;
            weight=0;
        }
        if(!weight) break;
    }
    printf("%.2lf
",ans);
}
View Code

L2-005 集合相似度

坑点:能尽量优化减少对于set的使用和遍历次数

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
set<int> s[maxn];
int main(){
    int n;scanf("%d",&n);
    rep(i,1,n){
        int t;scanf("%d",&t);
        while(t--){
            int x;scanf("%d",&x);
            s[i].insert(x);
        }
    }
    int k;scanf("%d",&k);
    while(k--){
        int a,b;scanf("%d%d",&a,&b);
        int cnt=0;
        for(auto it:s[b]){
            if(s[a].count(it)) ++cnt;
        }
        double ans=1.00*cnt/(s[a].size()+s[b].size()-cnt);
        printf("%.2lf%
",ans*100);
    }
}
View Code

L2-007家庭房产

题解:大模拟+bfs建边跑连通块维护连通块信息

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int tot,head[maxn];
struct E{
    int to,next;
}edge[maxn<<2];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n,a[maxn],num[maxn],s[maxn];
bool vis[maxn];
struct node{
    vector<int> vec;
    int num,s;
    int minn,t;
    double averT,averSIZ;
}p[maxn];
void bfs(int x,int id){
    queue<int> q;q.push(x);
    while(!q.empty()){
        int now=q.front();q.pop();
        p[id].vec.push_back(now);
        p[id].num+=num[now];
        p[id].s+=s[now];
        for(int i=head[now];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(vis[v]) continue;
            vis[v]=true;
            q.push(v);
        }
    }
}
bool cmp(node a,node b){
    if(a.averSIZ!=b.averSIZ) return a.averSIZ>b.averSIZ;
    else return a.minn<b.minn;
}
int main(){
    scanf("%d",&n);mem(head,-1);
    rep(i,1,n){
        int id,L,R;scanf("%d%d%d",&id,&L,&R);
        a[id]=1;
        if(L!=-1) a[L]=1,add(id,L),add(L,id);
        if(R!=-1) a[R]=1,add(id,R),add(R,id);
        int k;scanf("%d",&k);
        while(k--){
            int x;scanf("%d",&x);
            a[x]=1;
            add(id,x);add(x,id);
        }        
        scanf("%d%d",&num[id],&s[id]);
    }
    int cnt=0;
    for(int i=0;i<=9999;i++){
        if(a[i]&&!vis[i]){
            vis[i]=true;
            bfs(i,++cnt);
            p[cnt].minn=i;
        }
    }
    for(int i=1;i<=cnt;i++){
        p[i].minn=p[i].vec[0];
        p[i].t=p[i].vec.size();
        p[i].averT=1.000*p[i].num/p[i].t;
        p[i].averSIZ=1.000*p[i].s/p[i].t;
    }
    sort(p+1,p+cnt+1,cmp);
    cout<<cnt<<endl;
    rep(i,1,cnt){
        printf("%04d %d %.3lf %.3lf
",p[i].minn,p[i].t,p[i].averT,p[i].averSIZ);
    }
}
View Code

L2-008 最长对称子串

题解:马拉车算法模板裸题,输入用getline输入

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e7+5;
string s;
char str[maxn<<1];
int p[maxn<<1];
int init(){
    int len=s.length();
    str[0]='@',str[1]='#';
    int j=2;
    for(int i=0;i<len;i++) str[j++]=s[i],str[j++]='#';
    str[j]='';
    return j;
}
int manacher(){
    int ans=-1,len=init(),mx=0,id=0;
    for (int i=1;i<len;i++) {
        if(i<mx) p[i]=min(p[id*2-i],mx-i);
        else p[i]=1;
        while(str[i+p[i]]==str[i-p[i]]) p[i]++;
        if(p[i]+i>mx) mx=p[i]+i,id=i;
        ans=max(ans,p[i]-1);
    }
    return ans;
}

int main(){
    getline(cin,s);
    cout<<manacher();
    return 0;
} 
View Code

L2-009 抢红包

题解:模拟

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
struct node{
    int id,ct;double w;
}q[maxn];
int p[maxn],cnt[maxn];
bool cmp(node a,node b){
    if(a.w!=b.w) return a.w>b.w;
    else{
        if(a.ct!=b.ct) return a.ct>b.ct;
        else{
            if(a.id!=b.id) return a.id<b.id;
        }
    }
}
int main(){
    int n;scanf("%d",&n);
    rep(i,1,n){
        int k;scanf("%d",&k);
        while(k--){
            int a,b;scanf("%d%d",&a,&b);
            p[a]+=b;p[i]-=b;
            cnt[a]+=1;
        }
    }
    rep(i,1,n){
        q[i].ct=cnt[i],q[i].id=i;q[i].w=p[i];q[i].w/=100;
    }
    sort(q+1,q+n+1,cmp);
    rep(i,1,n){
        printf("%d %.2lf
",q[i].id,q[i].w);
    }
}
View Code

L2-010 排座位

题解:有点绕,理清楚逻辑关系用Floyd就行

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e2+5;
int d[maxn][maxn],r[maxn][maxn],z[maxn][maxn],fa[maxn];
int find(int x){
    while(x!=fa[x]) x=fa[x]=fa[fa[x]];
    return x;
}
int n,m,q;
int x[maxn][maxn];
int main(){
    scanf("%d%d%d",&n,&m,&q);
    rep(i,1,n) fa[i]=i;
    mem(d,INF);
    rep(i,1,m){
        int u,v,w;scanf("%d%d%d",&u,&v,&w);
        if(w==-1) d[u][v]=INF,d[v][u]=INF,x[u][v]=x[v][u]=1;
        else d[u][v]=0,d[v][u]=0,z[u][v]=z[v][u]=1;
        r[u][v]=r[v][u]=1;
        int eu=find(u),ev=find(v);
        if(eu!=ev){
            fa[ev]=eu;
        }
    }
    rep(i,1,n) d[i][i]=0;
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
        }
    }
    while(q--){
        int u,v;scanf("%d%d",&u,&v);
        if(find(u)==find(v)){
            if(z[u][v]) puts("No problem");
            else{
                if(!r[u][v]) {puts("OK");continue;}
                if(x[u][v]){
                    if(d[u][v]==0) puts("OK but...");
                    else puts("No way");
                }    
            }
        }else{
            puts("OK");
        }
    }
}
View Code

L2-013 红色警报

题解:因为n=500,所以可以暴力做法,每次执行2次dsu  。 或者反向加点

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=5000+5;
int tot,head[505];
struct E{
    int to,next;
}edge[maxn<<1];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n,m,vis[505],p[505];
void dfs(int x){
    vis[x]=1;
    for(int i=head[x];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v]||p[v]) continue;
        vis[v]=1;
        dfs(v);
    }
}
int main(){
    scanf("%d%d",&n,&m);mem(head,-1);
    rep(i,1,m){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    int q;scanf("%d",&q);int lol=0;
    while(q--){
        int x;scanf("%d",&x);++lol;
        for(int i=0;i<n;i++) vis[i]=0;
        int cnt=0;
        for(int i=0;i<n;i++){
            if(!vis[i]&&!p[i]){
                ++cnt;
                dfs(i);
            }
        }    
        p[x]=1;
        int ct=0;
        for(int i=0;i<n;i++) vis[i]=0;
        for(int i=0;i<n;i++){
            if(!vis[i]&&!p[i]){
                ++ct;
                dfs(i);
            }
        }
        if(ct-cnt>0) printf("Red Alert: City %d is lost!
",x);
        else printf("City %d is lost.
",x);
        if(lol==n) puts("Game Over.");    
    }
}
View Code

L2-014 列车调度

题解:和Hdoj的导弹拦截一样,推出规律就是LIS,但是要一个O(nlogn)的做法,否则会TLE

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int a[maxn],g[maxn],dp[maxn];
int main(){
    int n;scanf("%d",&n);
    rep(i,1,n) scanf("%d",&a[i]);
    mem(g,INF);int ans=-1;
    for(int i=1;i<=n;i++){
        int pos=lower_bound(g+1,g+n+1,a[i])-g;
        dp[i]=pos+1;
        if(ans<dp[i]) ans=dp[i];
        g[pos]=a[i];
    }
    cout<<ans-1<<endl;
}
View Code

L2-015 互评成绩

题解:模拟

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e4+5;
int n,m,k;
int a[maxn][12];
double ans[maxn];
int main(){
    scanf("%d%d%d",&n,&m,&k);
    rep(i,1,n){
        rep(j,1,m){
            scanf("%d",&a[i][j]);
        }
        sort(a[i]+1,a[i]+1+m);
        ans[i]=0;
        rep(j,2,m-1) ans[i]+=a[i][j];
        ans[i]=1.000*ans[i]/(m-2);
    }
    sort(ans+1,ans+n+1);
    rep(i,n-k+1,n){
        if(i!=n) printf("%.3lf ",ans[i]);
        else printf("%.3lf
",ans[i]);
    }
}
View Code

L2-019 悄悄关注

题解:模拟

#include<bits/stdc++.h>
#define endl '
'
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1e4+5;
string s[maxn];int cnt[maxn];
int main(){
    int n;cin>>n;
    map<string,int> mp;
    rep(i,1,n){
        string ss;cin>>ss;
        mp[ss]=1;    
    }
    int m;cin>>m;
    double sum=0;
    rep(i,1,m){
        cin>>s[i]>>cnt[i];
        sum+=cnt[i];
    }
    vector<string> vec;
    sum=1.000*sum/m;
    rep(i,1,m){
        if(!mp[s[i]]){
            if(cnt[i]>sum) vec.push_back(s[i]);
        }
    }
    if(!vec.size()) puts("Bing Mei You");
    else{
        sort(vec.begin(),vec.end());
        for(auto it:vec){
            cout<<it<<endl;
        }
    }
}
View Code

L2-020 功夫传人

坑点:祖师爷自己就是得道者,没有弟子,所以需要自己放大自己

#include<bits/stdc++.h>
#define endl '
'
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1e5+5;
int head[maxn],tot;
struct E{
    int to,next;
}edge[maxn<<1];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n;double z[maxn],r;
double b[maxn];int vis[maxn];
double sum;
void dfs(int x,int fa){
    for(int i=head[x];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        z[v]=z[x]*1.00*(100-r)/100*b[v];
        dfs(v,x);
    }
}
int main(){
    cin>>n>>z[0]>>r;
    memset(head,-1,sizeof(head));sum=0;
    for(int i=0;i<n;i++) b[i]=1.00;
    rep(i,0,n-1){
        int t;cin>>t;
        if(!t){
            cin>>b[i];vis[i]=1;
        }else{
            rep(j,1,t){
                int x;cin>>x;
                add(i,x);
            }
        }
    }
    z[0]*=b[0];
    dfs(0,-1);
    rep(i,0,n-1){
        if(vis[i]) sum+=z[i];
    }
    long long x=floor(sum);
    cout<<x<<endl;
}
View Code

L2-023 图着色问题

坑点:边的数量2.5e5,以及颜色数一定要等于k

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=3e5+5;
int tot,head[505];
struct E{
    int to,next;
}edge[maxn<<1];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n,m,k,col[505];
int main(){
    cin>>n>>m>>k;mem(head,-1);
    rep(i,1,m){
        int u,v;cin>>u>>v;
        add(u,v);add(v,u);
    }
    int t;cin>>t;
    while(t--){
        set<int> s;
        rep(i,1,n){
            cin>>col[i];
            s.insert(col[i]);
        }
        if(s.size()!=k){puts("No");continue;}
        rep(i,1,n){
            for(int j=head[i];j!=-1;j=edge[j].next){
                int v=edge[j].to;
                if(col[v]==col[i]){
                    puts("No");
                    goto end;
                }
            }
        }
        puts("Yes");
        end:;
    }
}
View Code

L2-024 部落

题解:图论建边,bfs标记连通块

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e7+5;
int tot,head[10005];
struct E{
    int to,next;
}edge[maxn<<1];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int vis[10005];
void bfs(int x,int id){
    queue<int> q;q.push(x);
    while(!q.empty()){
        int now=q.front();vis[now]=id;q.pop();
        for(int i=head[now];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(vis[v]) continue;
            vis[v]=id;
            q.push(v);
        }
    }    
}
int main(){
    int T;cin>>T;mem(head,-1);set<int> s;
    while(T--){
        int k;cin>>k;
        vector<int> vec;
        rep(i,1,k){
            int x;cin>>x;
            vec.pb(x);s.insert(x);
        }
        for(int i=1;i<vec.size();i++){
            add(vec[i-1],vec[i]);add(vec[i],vec[i-1]);
        }                
    }
    int cnt=0;
    for(int i=1;i<=s.size();i++){
        if(!vis[i]){
            bfs(i,++cnt);
        }
    }
    int q;cin>>q;
    vector<char> vec;
    while(q--){
        int u,v;cin>>u>>v;
        if(vis[u]==vis[v]) vec.pb('Y');
        else vec.pb('N');
    }
    cout<<s.size()<<" "<<cnt<<endl;    
    for(auto it:vec){
        cout<<it<<endl;
    }
}
View Code

L2-025 分而治之

题解:模拟,图论

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int tot,head[maxn];
struct E{
    int to,next;
}edge[maxn<<1];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n,m,vis[maxn];
int main(){
    cin>>n>>m;mem(head,-1);
    rep(i,1,m){
        int u,v;cin>>u>>v;
        add(u,v);add(v,u);
    }
    int T;cin>>T;
    queue<int> q;
    while(T--){
        int k;cin>>k;
        rep(i,1,k){
            int x;cin>>x;
            q.push(x);vis[x]=1;
        }
        rep(i,1,n){
            if(vis[i]) continue;
            for(int j=head[i];j!=-1;j=edge[j].next){
                int v=edge[j].to;
                if(!vis[v]){
                    puts("NO");
                    goto end;
                }
            }
        }
        puts("YES");
        end:;
        while(!q.empty()){
            int now=q.front();q.pop();
            vis[now]=0;
        }
    }
}
View Code

L2-026小字辈

题解:dfs

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int tot,head[maxn];
struct E{
    int to,next;
}edge[maxn<<1];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int id[maxn],maxx;
void dfs(int x,int level){
    id[x]=level;maxx=max(maxx,level);
    for(int i=head[x];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        dfs(v,level+1);
    }
}
int main(){
    int n,rt;maxx=-INF;cin>>n;mem(head,-1);
    rep(i,1,n){
        int x;cin>>x;
        if(x!=-1) add(x,i);
        else rt=i;
    }
    dfs(rt,1);
    cout<<maxx<<endl;
    vector<int> vec;
    rep(i,1,n){
        if(id[i]==maxx) vec.pb(i);
    }    
    for(int i=0;i<vec.size();i++){
        if(i==vec.size()-1) cout<<vec[i]<<endl;
        else cout<<vec[i]<<" ";
    }
}
View Code
原文地址:https://www.cnblogs.com/Anonytt/p/13795684.html