EZ的间谍网络

来源:互联网 发布:死刑知乎 编辑:程序博客网 时间:2024/04/18 12:17

wori……塔杨快写吐我了

基本思路:

首先先记录每个人会被钱收买的情况 然后bfs 假如所有人都被收买了还不能获得所有间谍的资料输出no

否则tarjan缩点记录入度 定义lowest为第i个环中最小的需要购买的

最后答案就是所有入度为0的点的lowest之和

#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<vector>using namespace std;const int INF = 0x7f7f7f7f;struct edge{    int from,to,pre;}Edge[20001];int belong[10001];int sccnumber;stack<int> s;int n,p,r;int dfn[10001],low[10001];bool instack[10001];int money[10001];int in[10001];int head[10001];bool vis[10001];int lowest[10001];int ind=0,cnt=0,topt=0;inline void addedge(int from,int to){    Edge[++cnt]=((edge){from,to,head[from]});    head[from]=cnt;}inline int init(){    int now=0;char c;bool flag=false;    while(1)    {        c=getchar();        if(c>='0'&&c<='9')        {            now=now*10+c-'0';            flag=true;        }        else if(flag)return now;    }}queue<int> q;void bfs(){    int now;    while(!q.empty())    {        now=q.front();q.pop();        if(vis[now])continue;        vis[now]=1;        for(int j=head[now];j;j=Edge[j].pre)        {            if(!vis[now]);q.push(Edge[j].to);        }    }}void tarjan(int now){    dfn[now]=low[now]=++ind;    s.push(now);instack[now]=true;    for(int j=head[now];j;j=Edge[j].pre)    {        if(!dfn[Edge[j].to])        {            tarjan(Edge[j].to);            low[now]=min(low[now],low[Edge[j].to]);        }        else if(instack[Edge[j].to])        {            low[now]=min(low[now],dfn[Edge[j].to]);        }    }    if(dfn[now]==low[now])    {        ++sccnumber;        lowest[sccnumber]=INF;        while(1)        {            topt=s.top();s.pop();            instack[topt]=false;            lowest[sccnumber]=min(lowest[sccnumber],money[topt]);            belong[topt]=sccnumber;            if(topt==now)break;        }    }}void rebuild(){    for(int i=1;i<=n;i++)    {            for(int j=head[i];j;j=Edge[j].pre)            {                if(belong[Edge[j].to]!=belong[i])                {                    in[belong[Edge[j].to]]=1;                }            }    }}int main(){    n=init();p=init();    int agent;    for(int i=1;i<=n;i++)    {        money[i]=INF;    }    for(int i=1;i<=p;i++)    {        agent=init();        money[agent]=init();        q.push(agent);    }    r=init();    int a,b;    for(int i=1;i<=r;i++)    {        a=init();b=init();        addedge(a,b);    }    bfs();    for(int i=1;i<=n;i++)    {        if(!vis[i])        {            cout<<"NO"<<endl;            cout<<i<<endl;            return 0;        }    }    int ans=0;    for(int i=1;i<=n;i++)    {        if(!belong[i])        {            tarjan(i);        }    }    rebuild();    for(int i=1;i<=sccnumber;i++)    {        if(!in[i])        {            ans+=lowest[i];        }    }    cout<<"YES"<<endl;    cout<<ans<<endl;    return 0;}


0 0
原创粉丝点击