CF893C Rumor
有n个人,其中有m对朋友,现在你有一个秘密你想告诉所有人,第i个人愿意出价a[i]买你的秘密,获得秘密的人会免费告诉它的所有朋友(他朋友的朋友也会免费知道),现在他们想出最少的价钱买秘密,那么你最少能得到多少钱?
刷水利于身心健康。
code:
#include#include #include #define int long longusing namespace std;const int wx=100017;inline int read(){ int sum=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();} return sum*f;}int head[wx],dfn[wx],low[wx],belong[wx];int a[wx],val[wx],st[wx];int n,m,ans,num,tot,top,col;struct e{ int nxt,to;}edge[wx*2];void add(int from,int to){ edge[++num].nxt=head[from]; edge[num].to=to; head[from]=num;}void Tarjan(int u){ dfn[u]=low[u]=++tot; st[++top]=u; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(!dfn[v]){ Tarjan(v); low[u]=min(low[u],low[v]); } else if(!belong[v]){ low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ belong[u]=++col; while(st[top]!=u){ belong[st[top]]=col; top--; }top--; }}signed main(){ n=read(); m=read(); for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=m;i++){ int x,y; x=read(); y=read(); add(x,y); add(y,x); } for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i); for(int i=1;i<=col;i++)val[i]=1e18; for(int i=1;i<=n;i++)val[belong[i]]=min(val[belong[i]],a[i]); for(int i=1;i<=col;i++)ans+=val[i]; printf("%lld\n",ans); return 0;}