[luogu1262]间谍网络
Posted neworld2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu1262]间谍网络相关的知识,希望对你有一定的参考价值。
考虑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]间谍网络的主要内容,如果未能解决你的问题,请参考以下文章