【HDU 3435】 A new Graph Game (KM|费用流)

A new Graph Game

Problem Description

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!)

Input

In 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)

Output

Output “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.

【题意】

  将一个无向图删边得到一些子图,并使每个子图中存在哈密顿回路,并使所有哈密顿回路上边的权值最小

【分析】

  形成哈密顿回路的话就是每个点入度出度都为0.拆点建二分图,然后KM。

这题要判断能不能完美匹配,这里修改一下模版!!

INF 那里要判断一下再减delta!!

代码如下:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<queue>
  7 using namespace std;
  8 #define Maxn 1010
  9 #define Maxm 10010
 10 #define INF 0xfffffff
 11
 12 struct node
 13 {
 14     int x,y,c,next;
 15 }t[Maxm*2];int len;
 16 int first[Maxn];
 17
 18 void ins(int x,int y,int c)
 19 {
 20     t[++len].x=x;t[len].y=y;t[len].c=-c;
 21     t[len].next=first[x];first[x]=len;
 22 }
 23
 24 int mymin(int x,int y) {return x<y?x:y;}
 25 int mymax(int x,int y) {return x>y?x:y;}
 26
 27 int lx[Maxn],ly[Maxn];
 28 int slack[Maxn],match[Maxn];
 29 bool visx[Maxn],visy[Maxn];
 30 int n;
 31
 32 bool ffind(int x)
 33 {
 34     visx[x]=1;
 35     for(int i=first[x];i;i=t[i].next) if(!visy[t[i].y])
 36     {
 37         int y=t[i].y;
 38         if(t[i].c==lx[x]+ly[y])
 39         {
 40             visy[y]=1;
 41             if(!match[y]||ffind(match[y]))
 42             {
 43                 match[y]=x;
 44                 return 1;
 45             }
 46         }
 47         else slack[y]=mymin(slack[y],lx[x]+ly[y]-t[i].c);
 48     }
 49     return 0;
 50
 51 }
 52
 53 bool solve()
 54 {
 55     memset(match,0,sizeof(match));
 56     memset(ly,0,sizeof(ly));
 57     for(int i=1;i<=n;i++)
 58     {
 59         lx[i]=-INF;
 60             // printf("%d\n",i);
 61         for(int j=first[i];j;j=t[j].next)
 62         {
 63             // printf("%d\n",j);
 64            lx[i]=mymax(lx[i],t[j].c);
 65
 66         }
 67     }
 68     int i;
 69     for(i=1;i<=n;i++)
 70     {
 71         for(int j=1;j<=n;j++) slack[j]=INF;
 72         while(1)
 73         {
 74             memset(visx,0,sizeof(visx));
 75             memset(visy,0,sizeof(visy));
 76             if(ffind(i)) break;
 77             int delta=INF;
 78             for(int j=1;j<=n;j++) if(!visy[j])
 79                 delta=mymin(delta,slack[j]);
 80             if(delta==INF) return 0;
 81             for(int j=1;j<=n;j++)
 82             {
 83                 if(visx[j]) lx[j]-=delta;
 84                 if(visy[j]) ly[j]+=delta;
 85                 else if(slack[j]!=INF) slack[j]-=delta;
 86             }
 87         }
 88     }
 89     return 1;
 90 }
 91
 92 int main()
 93 {
 94     int T,kase=0;
 95     scanf("%d",&T);
 96     while(T--)
 97     {
 98         int m;
 99         scanf("%d%d",&n,&m);
100         len=0;
101         memset(first,0,sizeof(first));
102         for(int i=1;i<=m;i++)
103         {
104             int x,y,c;
105             scanf("%d%d%d",&x,&y,&c);
106             ins(x,y,c);ins(y,x,c);
107         }
108         printf("Case %d: ",++kase);
109         if(solve())
110         {
111             int ans=0;
112             for(int i=1;i<=n;i++) ans+=lx[i]+ly[i];
113             printf("%d\n",-ans);
114         }
115         else printf("NO\n");
116     }
117     return 0;
118 }

[HDU 3435]

2016-10-27 11:12:02

时间: 2024-10-10 22:30:32

【HDU 3435】 A new Graph Game (KM|费用流)的相关文章

hdu 1853 Cyclic Tour &amp;&amp; hdu 3435 A new Graph Game(简单KM算法)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1478    Accepted Submission(s): 750 Problem Description There are N cities in our country, and M one-way roads connecting them. Now L

HDU 4862 Jump 最小k路径覆盖 费用流

gg... 题意: 给定n*m的矩阵 选<=k个起点 每个起点可以向右或向下跳任意步 花费是2点间的曼哈顿距离 若2个格子的数字一样 则赚取格子上的数字的价值 问:遍历整个图的最小花费 若不能遍历则输出-1 #include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <set> #in

HDU 2448 Mining Station on the Sea 费用流

Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2123    Accepted Submission(s): 642 Problem Description The ocean is a treasure house of resources and the development o

HDU 3435 A new Graph Game(最小费用流:有向环权值最小覆盖)

http://acm.hdu.edu.cn/showproblem.php?pid=3435 题意:有n个点和m条边,你可以删去任意条边,使得所有点在一个哈密顿路径上,路径的权值得最小. 思路: 费用流,注意判断重边,否则会超时. 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<queue> 6 using names

HDU 2485 Destroying the bus stations(费用流)

http://acm.hdu.edu.cn/showproblem.php?pid=2485 题意: 现在要从起点1到终点n,途中有多个车站,每经过一个车站为1时间,现在要在k时间内到达终点,问至少要破坏多少个车站. 思路: 把每个点拆分为两个点,容量为1,费用为0.之后相邻的车站连边,容量为INF,费用为1,表示经过一个车站需要1时间. 这样一来,跑一遍费用流计算出在费用不大于k的情况下的最大流,也就是最小割,即至少要破坏的车站数. 在网络中寻求关于f的最小费用增广路,就等价于在伴随网络中寻求

HDU 2686 Matrix 3376 Matrix Again(费用流)

HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,只是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 思路:拆点,建图,然后跑费用流即可,不过HDU3376这题,极限情况是300W条边,然后卡时间过了2333 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #i

HDU 3435 A new Graph Game(最小费用最大流)&amp;amp;HDU 3488

A new Graph Game Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1849    Accepted Submission(s): 802 Problem Description An undirected graph is a graph in which the nodes are connected by undir

HDU 3435 A new Graph Game(最小费用最大流)&amp;HDU 3488

A new Graph Game Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1849    Accepted Submission(s): 802 Problem Description An undirected graph is a graph in which the nodes are connected by undir

HDU 3316 My Brute(二维费用流)经典

My Brute Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 941    Accepted Submission(s): 372 Problem Description Seaco is a beautiful girl and likes play a game called "My Brute". Before Va