申请增加数据
查看原帖
申请增加数据
660370
MysterySwordman楼主2023/3/1 14:54
以下下错误代码可以过掉此题。
输入
4
1
3 5
3
4 2
2 3
3 1
以下代码错误输出
NO
4
正确输出
NO
2
#include<bits/stdc++.h>
using namespace std;
const int N=3e3+10,M=8e3+10;
int n,m,p,idx,timestamp,scc_cnt;
int e[M],ne[M],h[N],w[N];
int dfn[N],low[N],id[N];
int stk[N],in_stk[N],top;
int min_f[N],din[N],d[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void tarjan(int u){
    dfn[u]=low[u]=++timestamp;
    stk[++top]=u;
    in_stk[u]=1;
    for(int i=h[u];~i;i=ne[i]){
        int j=e[i];
        if(!dfn[j]){
            tarjan(j);
            low[u]=min(low[u],low[j]);
        }
        else if(in_stk[j]){
            low[u]=min(low[u],dfn[j]);
        }
    }
    if(dfn[u]==low[u]){
        int t;
        scc_cnt++;
        do{
            t=stk[top--];
            in_stk[t]=0;
            id[t]=scc_cnt;
            if(w[t])min_f[scc_cnt]=min(min_f[scc_cnt],w[t]);
        }while(t!=u);
    }
}
int main(){
    memset(h,-1,sizeof h);
    memset(min_f,0x3f,sizeof min_f);
    scanf("%d%d",&n,&p);
    while(p--){
        int x,c;
        scanf("%d%d",&x,&c);
        w[x]=c;
    }
    scanf("%d",&m);
    while(m--){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        din[b]++;
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i])tarjan(i);
    }
    int res=-1;
    for(int i=1;i<=n;i++){
        if(w[i])continue;
        if(!din[i]){//这里出了问题,度数不为0时也可以无法控制住这个间谍
            res=i;//4->2->3->1(只有3可以被贿赂),比如这个情况
            break;
        }
    }
    if(~res){
        puts("NO");
        printf("%d",res);
    }
    else{
        puts("YES");
        for(int i=1;i<=n;i++){
            for(int j=h[i];~j;j=ne[j]){
                int k=e[j];
                int a=id[i],b=id[k];
                if(a!=b)d[b]++; 
            }
        }
        res=0;
        for(int i=1;i<=scc_cnt;i++){
            if(!d[i])res+=min_f[i];
        }
        printf("%d",res);
    }
    return 0;
}
2023/3/1 14:54
加载中...