POJ 2125 Destroying The Graph (dinic求最小点权覆盖)
来源:互联网 发布:xbox360淘宝 编辑:程序博客网 时间:2024/06/06 12:21
Destroying The Graph
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 5865 Accepted: 1864 Special Judge
Description
Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After that Bob tries to destroy it. In a move he may take any vertex of the graph and remove either all arcs incoming into this vertex, or all arcs outgoing from this vertex.
Alice assigns two costs to each vertex: Wi+ and Wi-. If Bob removes all arcs incoming into the i-th vertex he pays Wi+ dollars to Alice, and if he removes outgoing arcs he pays Wi- dollars.
Find out what minimal sum Bob needs to remove all arcs from the graph.
Alice assigns two costs to each vertex: Wi+ and Wi-. If Bob removes all arcs incoming into the i-th vertex he pays Wi+ dollars to Alice, and if he removes outgoing arcs he pays Wi- dollars.
Find out what minimal sum Bob needs to remove all arcs from the graph.
Input
Input file describes the graph Alice has drawn. The first line of the input file contains N and M (1 <= N <= 100, 1 <= M <= 5000). The second line contains N integer numbers specifying Wi+. The third line defines Wi- in a similar way. All costs are positive and do not exceed 106 . Each of the following M lines contains two integers describing the corresponding arc of the graph. Graph may contain loops and parallel arcs.
Output
On the first line of the output file print W --- the minimal sum Bob must have to remove all arcs from the graph. On the second line print K --- the number of moves Bob needs to do it. After that print K lines that describe Bob's moves. Each line must first contain the number of the vertex and then '+' or '-' character, separated by one space. Character '+' means that Bob removes all arcs incoming into the specified vertex and '-' that Bob removes all arcs outgoing from the specified vertex.
Sample Input
3 61 2 34 2 11 21 13 21 23 12 3
Sample Output
531 +2 -2 +
Source
Northeastern Europe 2003, Northern Subregion
题意:给你一张图,有N个点和M条边,然后你要在这N个点中选取几个点移除,没取一个点,就删去与之有关的弧。如果如果删去该点的所有出度,要花去W-的费用,删去所有入度就要花去W+的费用。问花费最小的费用取点删去所有的边。
思路:最小点权覆盖,可以当做是最小割,挺好好建图的,就是最后遍历求如何取点想了挺久......
我们首先设源点s和汇点t,然后把每个点拆分成两个点。对于a->b有连接的边,我们连接一条(a,n+b,oo)的边,oo为无穷大,n+b为b点拆分的点。然后对于所有点从s到i连接一条权值为W-的边,从i+n到t连接一条权值为W+的边。
其实是二分匹配。这里求出的最大流就是最小割,最小割就是最小点权覆盖。
对于最后的取点,因为求的是最小割,那么从s开始遍历,对于i<=n不能遍历到的点,也就是被取走了,输出i -,对于能遍历到的点,并且i>n,说明与之相连的j->i,之前的s->j的边不是最小割,j不取,i是最小割中的点,所以输出i +。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int mm=100000;const int mn=300;const int oo=1000000000;int node,s,t,edge;int to[mm],flow[mm],next[mm];int head[mn],work[mn],dis[mn],q[mn];bool vis[mn];inline int min(int a,int b){ return a<b?a:b;}inline void init(int nn,int ss,int tt){ node=nn,s=ss,t=tt,edge=0; for(int i=0; i<node; ++i) head[i]=-1;}inline void add(int u,int v,int c){ to[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++; to[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;}bool bfs(){ int i,u,v,l,r=0; for(i=0; i<node; ++i) dis[i]=-1; dis[q[r++]=s]=0; for(l=0; l<r; ++l) for(i=head[u=q[l]]; i>=0; i=next[i]) if(flow[i]&&dis[v=to[i]]<0) { dis[q[r++]=v]=dis[u]+1; if(v==t)return 1; } return 0;}int dfs(int u,int maxf){ if(u==t) return maxf; for(int &i=work[u],v,tmp; i>=0; i=next[i]) if(flow[i]&&dis[v=to[i]]==dis[u]+1&&(tmp=dfs(v,min(maxf,flow[i])))>0) { flow[i]-=tmp; flow[i^1]+=tmp; return tmp; } return 0;}int dinic(){ int i,ret=0,delta; while(bfs()) { for(i=0; i<node; ++i) work[i]=head[i]; while(delta=dfs(s,oo))ret+=delta; } return ret;}void flag(int now){ vis[now]=1; for(int i=head[now]; ~i; i=next[i]) { if(flow[i]&&!vis[to[i]]) flag(to[i]); }}int main(){ int n,m,u,v,i,cost,cnt; while(cin>>n>>m) { init(2*n+2,0,2*n+1); memset(vis,0,sizeof(vis)); cnt=0; for(i=n+1; i<=2*n; i++) { scanf("%d",&cost); add(i,t,cost); } for(i=1; i<=n; i++) { scanf("%d",&cost); add(s,i,cost); } while(m--) { scanf("%d%d",&u,&v); add(u,v+n,oo); } int ans=dinic(); printf("%d\n",ans); flag(s); for(i=1; i<=2*n; i++) { if(vis[i]&&i>n) cnt++; else if(!vis[i]&&i<=n) cnt++; } printf("%d\n",cnt); for(i=1; i<=2*n; i++) { if(vis[i]&&i>n) printf("%d +\n",i-n); else if(!vis[i]&&i<=n) printf("%d -\n",i); } } return 0;}
- POJ 2125 Destroying The Graph (dinic求最小点权覆盖)
- POJ 2125 Destroying The Graph 最小点权覆盖
- POJ 2125 Destroying The Graph 最小点权覆盖集
- 【POJ】2125 Destroying The Graph 最小点权覆盖
- poj 2125 Destroying The Graph 最小点权覆盖
- Destroying The Graph (poj 2125 最小点权覆盖)
- poj 2125 Destroying The Graph 最小点权覆盖集
- poj 2125 Destroying The Graph(最小点权覆盖集)
- poj 2125 Destroying The Graph(最小割,最小点权覆盖)
- POJ 2125 Destroying The Graph 二分图最小点权覆盖 最小割
- POJ 2125 Destroying The Graph (最小点权覆盖集)
- 【二分图|最小点权覆盖】POJ-2125 Destroying The Graph
- POJ 2125 Destroying The Graph(二分图最小点权覆盖)
- POJ 2125 Destroying The Graph 二分图最小点权覆盖集
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- How to compile and debug VLC player source code in eclipse IDE on Ubuntu 10.04 (lucid)
- 下拉框输入文本
- proc文件的读写函数
- P2P 技术方案
- IAR学习笔记(摘抄)
- POJ 2125 Destroying The Graph (dinic求最小点权覆盖)
- Java Design Demo--多线程(一)线程唤醒
- Verilog HDL数据类型
- vc中异常捕捉的最后一道屏障-SetUnhandledExceptionFilter
- makefile中的宏
- 20 求平均年龄 各班平均分
- android 3.1以上boot complete receiver接受的问题
- CSP平台银联前置系统ATM他带本和本代他交易失败原因分析
- 11198 - Dancing Digits