[luogu1262]間諜網絡
阿新 • • 發佈:2018-08-30
memset efi urn clu algorithm cstring continue tarjan 我們
傳送門
考慮tarjan縮點,形成一個DAG。若要控制所有間諜,則從所有可以被控制的點出發,可以遍歷整個圖,否則就是存在無法控制。為了控制所有人,我們需要把入度為0的點的權值相加作為答案。
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 3005 #define MAXM 8005 #define INF 2147483647 int head[MAXN]; struct edge{ int v,next; }G[MAXM]; int u[MAXM],v[MAXM]; struct Node{ int cost,u; }E[MAXN]; int color[MAXN],value[MAXN],size[MAXN],least[MAXN]; int vis[MAXN],st[MAXN],top = 0; int dfn[MAXN],low[MAXN]; int N,P,R; int tot = 0,color_num = 0,num = 0; inline void add(int u,int v){ G[++tot].v = v;G[tot].next = head[u];head[u] = tot; } void tarjan(int u){ dfn[u] = low[u] = ++num; vis[u] = 1;st[++top] = u; for(register int i=head[u];i;i=G[i].next){ int v = G[i].v; if(!dfn[v]){ tarjan(v); if(low[v]<low[u])low[u] = low[v]; } else if(vis[v]&&low[u]>dfn[v])low[u] = dfn[v]; } if(low[u]==dfn[u]){ ++color_num;color[u] = color_num; vis[u] = 0; least[color_num] = u; while(st[top]!=u){ vis[st[top]] = 0; color[st[top]] = color_num; if(least[color_num]>st[top])least[color_num] = st[top]; top--; } top--; } } void dfs(int u){ dfn[u] = ++num; for(register int i=head[u];i;i=G[i].next){ if(!dfn[G[i].v])dfs(G[i].v); } } int main(){ std::memset(vis,0,sizeof(vis)); std::memset(head,0,sizeof(head)); std::memset(G,0,sizeof(G)); std::memset(dfn,0,sizeof(dfn)); scanf("%d",&N); scanf("%d",&P); for(register int i=1;i<=P;++i){ scanf("%d%d",&E[i].u,&E[i].cost); } scanf("%d",&R); for(register int i=1;i<=R;++i){ scanf("%d%d",&u[i],&v[i]); add(u[i],v[i]); } for(register int i=1;i<=N;++i){ if(!dfn[i])tarjan(i); } std::memset(dfn,0,sizeof(dfn)); std::memset(head,0,sizeof(head)); std::memset(G,0,sizeof(G)); std::memset(size,0,sizeof(size)); for(register int i=1;i<=R;++i){ if(color[u[i]]==color[v[i]])continue; add(color[u[i]],color[v[i]]); size[color[v[i]]]++; } for(register int i=1;i<=color_num;++i){ value[i] = INF; } for(register int i=1;i<=P;++i){ value[color[E[i].u]] = std::min(value[color[E[i].u]],E[i].cost); } num = 0; for(register int i=1;i<=color_num;++i){ if(value[i]!=INF&&!dfn[i]){ dfs(i); } } int ans = INF; for(register int i=1;i<=color_num;++i){ if(!dfn[i])ans = std::min(ans,least[i]); } if(ans!=INF){ puts("NO"); printf("%d",ans); return 0; } ans = 0; for(register int i=1;i<=color_num;++i){ if(!size[i])ans += value[i]; } puts("YES"); printf("%d",ans); return 0; }
[luogu1262]間諜網絡