【图论】[Tyvj 1153]间谍网络
2015-07-22 09:06
555 查看
实际上就是先找出整个图里面的强连通分量,然后在每一个强连通子图里面,如果有可以受贿的罪犯,那么当前值就是最小的受贿的代价,否则就是INF, 然后在有向无环图中搞DP就好了。
[code]#include <cstdio> #include <algorithm> #include <stack> #include <iostream> #include <vector> #include <cstring> using namespace std; const int MAXN = 3000; const int INF = 1000000000; const int MAXM = 16000; struct node{ int v; node *next; }Edges[MAXM+10], *adj[MAXN+10], *ecnt=Edges, *adj2[MAXN+10]; int kcnt, Min[MAXN+10], Minpeo[MAXN+10], Pid[MAXN+10], spend[MAXN+10], n; stack<int> sta; bool insta[MAXN+10]; vector<int> begin; void addedge(int u, int v){ ++ecnt; ecnt->v = v; ecnt->next = adj[u]; adj[u] = ecnt; } void addedge2(int u, int v){ ++ecnt; ecnt->v = v; ecnt->next = adj2[u]; adj2[u] = ecnt; } int dfn[MAXN+10], low[MAXN+10], dcnt, tmp; void dfs1(int u, int fa){ dfn[u] = low[u] = ++dcnt; sta.push(u); insta[u] = true; for(node *p=adj[u];p;p=p->next){ if(!dfn[p->v]){ dfs1(p->v, u); low[u] = min(low[u], low[p->v]); }else if(insta[p->v]) low[u] = min(low[u], dfn[p->v]); } if(dfn[u] == low[u]){ ++kcnt; Minpeo[kcnt] = INF; Min[kcnt] = INF; do{ tmp = sta.top(); sta.pop(); Pid[tmp] = kcnt; Min[kcnt] = min(Min[kcnt], spend[tmp]); Minpeo[kcnt] = min(Minpeo[kcnt], tmp); }while(tmp!=u); } insta[u] = false; } void prepare(){ for(int i=1;i<=n;i++) if(!dfn[i]) dfs1(i, -1); for(int i=1;i<=n;i++) for(node *p=adj[i];p;p=p->next) if(Pid[p->v] != Pid[i]) addedge2(Pid[i], Pid[p->v]); } void dfs2(int u, int _Min){ for(node *p=adj2[u];p;p=p->next){ if(Min[p->v] == INF) dfs2(p->v, _Min); Min[p->v] = 0; } } void GetAns(){ //for(int i=1;i<=n;i++) printf("%d-%d\n", i, Pid[i]); int Len = begin.size();//for(int i=1;i<=kcnt;i++) printf("%d\n", Min[i]); for(int i=0;i<Len;i++) dfs2(Pid[begin[i]], Min[Pid[begin[i]]]); int Print = INF; for(int i=1;i<=kcnt;i++) if(Min[i] == INF) Print = min(Print, Minpeo[i]); if(Print != INF){ printf("NO\n%d\n", Print); return ; } int sum = 0; for(int i=1;i<=kcnt;i++) sum += Min[i]; printf("YES\n%d\n", sum); } int main(){ scanf("%d", &n); int r, id, pd; scanf("%d", &r); for(int i=1;i<=n;i++) spend[i] = INF; for(int i=0;i<r;i++){ scanf("%d%d", &id, &pd); spend[id] = pd; begin.push_back(id); } scanf("%d", &r); for(int i=0;i<r;i++){ scanf("%d%d", &id, &pd); addedge(id, pd); } prepare(); GetAns(); return 0; }
相关文章推荐
- 大文件/数据网络传输方法总结(转载)
- 源泉书签,助您管理海量收藏。今日更新【里程碑】支持书签导出功能了,从此不怕网络书签丢失了,随时随地备份您的书签。
- 游戏引擎网络开发者的 64 做与不做 | Part 1 | 客户端方面
- 【算法笔记】总结 - 网络流 Edmonds-Karp 算法和 dinic 算法
- 安装OpenStack前CentOS7网络基本配置
- GO语言练习:实现最简单的http helloword 服务器
- 在Lighttpd服务器中运行Django应用的方法
- 网络工程师30个经典的电脑使用技巧
- 解决IISASP调用XmlHTTP出现msxml3.dll (0x80070005) 拒绝访问的错误
- 解决IISASP调用XmlHTTP出现msxml3.dll (0x80070005) 拒绝访问的错误
- 如何使用谷歌的网页删除请求工具?
- 今天实在忍不住,把极速星空的密码给破了
- 准备开发一个PSP专用的网站http://www.mypsp.com.cn
- WireShark 网络包过滤
- C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)【转】
- 解决网络通信中的中文乱码问题(Java)
- keepalived+lvs 实现tcp负载均衡
- HTTP Status 500 - org.apache.jasper.JasperException: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException
- 使用httpFS访问hdfs
- VMware网络模式介绍