博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【洛谷1262】间谍网络
阅读量:5066 次
发布时间:2019-06-12

本文共 2875 字,大约阅读时间需要 9 分钟。

tarjan缩点后找入度为零的强连通分量,加上它的sum即可

但注意到还有NO的可能,

所以大致有两种方法:

1.tarjan之前先来一遍bfs

2.tarjan内加一个数组维护最小编号

貌似前者比较好写qwq

1 #include
2 #include
3 using namespace std; 4 const int N=3010,M=6020; 5 const int novis=-1,nowvis=1,over=0; 6 int value[N],sum[N],flag[N],vis[N],que[M],n; 7 int head[M],next[M],to[M],size; 8 int low[N],dfn[N],color[N],in[N],sig,cnt,top; 9 void bfs(int),uni(int,int),tarjan(),dfs(int),rebuild(); 10 int min(int,int); 11 int main(){ 12 int x,y,p,r,tmp,ans; 13 ans=size=0; 14 memset(vis,0,sizeof(vis)); 15 memset(sum,0,sizeof(sum)); 16 memset(flag,0,sizeof(flag)); 17 memset(in,0,sizeof(in)); 18 scanf("%d %d",&n,&p); 19 for (int i=1;i<=n;i++) 20 value[i]=10000001;//初始化最大值便于后面sum取min 21 for (int i=1;i<=p;i++){ 22 scanf("%d %d",&x,&y); 23 value[x]=y; 24 flag[x]=1; 25 } 26 scanf("%d",&r); 27 for (int i=1;i<=r;i++){ 28 scanf("%d %d",&x,&y); 29 uni(x,y); 30 } 31 for (int i=1;i<=n;i++) 32 if (!vis[i]) bfs(i); 33 for (int i=1;i<=n;i++) 34 if (!vis[i]&&!flag[i]){ 35 printf("NO\n%d",i); 36 return 0; 37 } 38 tarjan(); 39 for (int i=1;i<=cnt;i++) 40 if (!in[i]) ans+=sum[i]; 41 printf("YES\n%d",ans); 42 return 0; 43 } 44 void uni(int x,int y){ 45 size++; 46 next[size]=head[x]; 47 head[x]=size; 48 to[size]=y; 49 } 50 void bfs(int x){ 51 int r,l,u,v; 52 l=0;r=1;que[1]=x; 53 while (l<=r){ 54 u=que[++l]; 55 for (int e=head[u];e;e=next[e]){ 56 v=to[e]; 57 if (!vis[v]) que[++r]=v; 58 vis[v]=1; 59 } 60 } 61 } 62 void tarjan(){ 63 memset(flag,novis,sizeof(flag)); 64 sig=cnt=top=0; 65 for (int i=1;i<=n;i++) 66 if (flag[i]==novis) dfs(i); 67 rebuild(); 68 } 69 void dfs(int x){ 70 que[++top]=x; 71 flag[x]=nowvis; 72 low[x]=dfn[x]=++sig; 73 for (int e=head[x];e;e=next[e]){ 74 int y=to[e]; 75 if (flag[y]==novis){ 76 dfs(y); 77 low[x]=min(low[x],low[y]); 78 } 79 else if (flag[y]==nowvis) 80 low[x]=min(low[x],dfn[y]); 81 } 82 if (low[x]==dfn[x]){ 83 cnt++;int t; 84 if (!sum[cnt]) sum[cnt]=20001; 85 do{ 86 t=que[top--]; 87 flag[t]=over; 88 color[t]=cnt; 89 sum[cnt]=min(sum[cnt],value[t]); 90 }while (t!=x); 91 } 92 } 93 void rebuild(){
//入度 94 for (int u=1;u<=n;u++) 95 for (int e=head[u];e;e=next[e]){ 96 int v=to[e]; 97 if (color[u]!=color[v]) 98 in[color[v]]++; 99 }100 }101 int min(int x,int y){102 return x
STD

 

转载于:https://www.cnblogs.com/Absolute-Zero/p/5876727.html

你可能感兴趣的文章
Unity 3D游戏开发学习路线(方法篇)
查看>>
BZOJ2049[Sdoi2008]Cave 洞穴勘测(LCT模板)
查看>>
vuex插件
查看>>
2011年12月09日
查看>>
[ZJOI2007]棋盘制作 【最大同色矩形】
查看>>
IOS-图片操作集合
查看>>
模板统计LA 4670 Dominating Patterns
查看>>
泛型第23条:请不要在新代码中使用原生态类型
查看>>
团队项目开发客户端——登录子系统的设计
查看>>
【AppScan心得】IBM Rational AppScan 无法记录登录序列
查看>>
[翻译] USING GIT IN XCODE [4] 在XCODE中使用GIT[4]
查看>>
简化通知中心的使用
查看>>
IO—》Properties类&序列化流与反序列化流
查看>>
html 简介
查看>>
session如何保存在专门的StateServer服务器中
查看>>
react展示数据
查看>>
测试计划
查看>>
选择器
查看>>
Mysql与Oracle 的对比
查看>>
idea的maven项目无法引入junit
查看>>