hdu 3435 A new Graph Game (费用流处理环)@
2017-01-22 17:35
239 查看
An undirected graph is a graph in which the nodes are connected by undirected arcs. An undirected arc is an edge that has no arrow. Both ends of an undirected arc are equivalent--there is no head or tail. Therefore, we represent an
edge in an undirected graph as a set rather than an ordered pair.
Now given an undirected graph, you could delete any number of edges as you wish. Then you will get one or more connected sub graph from the original one (Any of them should have more than one vertex).
You goal is to make all the connected sub graphs exist the Hamiltonian circuit after the delete operation. What’s more, you want to know the minimum sum of all the weight of the edges on the “Hamiltonian circuit” of all the connected sub graphs (Only one “Hamiltonian
circuit” will be calculated in one connected sub graph! That is to say if there exist more than one “Hamiltonian circuit” in one connected sub graph, you could only choose the one in which the sum of weight of these edges is minimum).
For example, we may get two possible sums:
(1) 7 + 10 + 5 = 22
(2) 7 + 10 + 2 = 19
(There are two “Hamiltonian circuit” in this graph!)
InputIn the first line there is an integer T, indicates the number of test cases. (T <= 20)
In each case, the first line contains two integers n and m, indicates the number of vertices and the number of edges. (1 <= n <=1000, 0 <= m <= 10000)
Then m lines, each line contains three integers a,b,c ,indicates that there is one edge between a and b, and the weight of it is c . (1 <= a,b <= n, a is not equal to b in any way, 1 <= c <= 10000)
OutputOutput “Case %d: “first where d is the case number counted from one. Then output “NO” if there is no way to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation. Otherwise, output the minimum
sum of weight you may get if you delete the edges in the optimal strategy.
Sample Input
Sample Output
Hint
In Case 1:
You could delete edge between 1 and 2 whose weight is 5.
In Case 2:
It’s impossible to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation.
费用流,求哈密顿回路,类似于二分匹配,个数相同一定会形成环,边数过多时,需要预处理,如果可能爆,建议手写队列
edge in an undirected graph as a set rather than an ordered pair.
Now given an undirected graph, you could delete any number of edges as you wish. Then you will get one or more connected sub graph from the original one (Any of them should have more than one vertex).
You goal is to make all the connected sub graphs exist the Hamiltonian circuit after the delete operation. What’s more, you want to know the minimum sum of all the weight of the edges on the “Hamiltonian circuit” of all the connected sub graphs (Only one “Hamiltonian
circuit” will be calculated in one connected sub graph! That is to say if there exist more than one “Hamiltonian circuit” in one connected sub graph, you could only choose the one in which the sum of weight of these edges is minimum).
For example, we may get two possible sums:
(1) 7 + 10 + 5 = 22
(2) 7 + 10 + 2 = 19
(There are two “Hamiltonian circuit” in this graph!)
InputIn the first line there is an integer T, indicates the number of test cases. (T <= 20)
In each case, the first line contains two integers n and m, indicates the number of vertices and the number of edges. (1 <= n <=1000, 0 <= m <= 10000)
Then m lines, each line contains three integers a,b,c ,indicates that there is one edge between a and b, and the weight of it is c . (1 <= a,b <= n, a is not equal to b in any way, 1 <= c <= 10000)
OutputOutput “Case %d: “first where d is the case number counted from one. Then output “NO” if there is no way to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation. Otherwise, output the minimum
sum of weight you may get if you delete the edges in the optimal strategy.
Sample Input
3 3 4 1 2 5 2 1 2 2 3 10 3 1 7 3 2 1 2 3 1 2 4 2 2 1 2 3 1 2 4
Sample Output
Case 1: 19 Case 2: NO Case 3: 6
Hint
In Case 1:
You could delete edge between 1 and 2 whose weight is 5.
In Case 2:
It’s impossible to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation.
费用流,求哈密顿回路,类似于二分匹配,个数相同一定会形成环,边数过多时,需要预处理,如果可能爆,建议手写队列
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> using namespace std; const int N = 1e5+10; const int M = 1010*2; int head[M], cnt; struct node { int from, to, cap, cost, next; }p ; void add(int u,int v,int w,int z) { p[cnt].from=u, p[cnt].to=v, p[cnt].cap=w, p[cnt].cost=z, p[cnt].next=head[u], head[u]=cnt++; p[cnt].from=v, p[cnt].to=u, p[cnt].cap=0, p[cnt].cost=-z, p[cnt].next=head[v], head[v]=cnt++; return ; } int d[M], pre[M], vis[M]; int q[M+10]; const int inf = 999999999; int min_cost_flow(int s,int t,int f) { int res=0; while(f>0) { int head1=0, tail=1; q[head1]=s; for(int i=0;i<=t;i++) d[i]=inf; memset(pre,-1,sizeof(pre)); memset(vis,0,sizeof(vis)); vis[s]=1, d[s]=0; while(head1!=tail) { int u=q[head1++]; head1%=M; for(int i=head[u];i!=-1;i=p[i].next) { int v=p[i].to; if(d[v]>d[u]+p[i].cost&&p[i].cap>0) { d[v]=d[u]+p[i].cost; pre[v]=i; if(!vis[v]) { vis[v]=1; if (p[i].cost<0) { head1=(head1-1+M)%M; q[head1]=p[i].to; } else { q[tail++]=p[i].to; tail%=M; } } } } vis[u]=0; } if(d[t]==inf) return -1; int flow=f; for(int i=pre[t];i!=-1;i=pre[p[i].from]) { flow=min(flow,p[i].cap); } res+=flow*d[t]; for(int i=pre[t];i!=-1;i=pre[p[i].from]) { p[i].cap-=flow, p[1^i].cap+=flow; } f-=flow; } return res; } typedef pair<int,int>px; vector<px>qx; int sx[1010][1010]; int main() { int t, n, m, ncase=1; scanf("%d", &t); while(t--) { memset(head,-1,sizeof(head)); memset(sx,0,sizeof(sx)); cnt=0; scanf("%d %d", &n, &m); int s=0, t=2*n+1; for(int i=0;i<m;i++) { int x, y, z; scanf("%d %d %d", &x, &y, &z); if(x>y) swap(x,y); if(!sx[x][y]) sx[x][y]=z; else sx[x][y]=min(z,sx[x][y]); } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(!sx[i][j]) continue; add(i,n+j,1,sx[i][j]); add(j,n+i,1,sx[i][j]); } } for(int i=1;i<=n;i++) add(0,i,1,0), add(n+i,t,1,0); int k=min_cost_flow(s,t,n); if(k==-1) printf("Case %d: NO\n",ncase++); else printf("Case %d: %d\n",ncase++,k); } return 0; }
相关文章推荐
- HDU1804——字符串处理
- Hdu 2167输入处理
- hdu 3973 AC's String 字符串哈希处理 查询子串是否是模式串 可以修改
- 广告费用 会计处理及其改进
- hdu 1853 费用流
- 【二维费用背包】HDU 2159
- hdu 3987 Harry Potter and the Forbidden Forest 求将s和t隔开的最少费用下的最小边数 最小割
- HDU Random Maze (欧拉路、费用流)
- R12应付款模块的费用报表(Expense Report)处理流程
- R12应付款模块的费用报表(Expense Report)处理流程
- 字符串处理,以HDU 2100为例
- hdu 2159 二维费用完全背包
- HDU 1039 字符串处理
- Bus System hdu 1690 (最短路 + long long int 处理)
- HDU 1020 Encoding (字符串处理)
- HDU1200——字符串处理
- 【W】HDU2206——字符串处理(IP计算)
- hdu 4054 字符串处理
- hdu 2159 二维费用背包
- hdu 1219(字符串处理)