HDU3435-A new Graph Game KM

来源:互联网 发布:northwind数据库下载 编辑:程序博客网 时间:2024/04/30 12:48

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

题意:题目看着乱乱哒,其实就是一个hdu1853的变种表达啦。

思路:求环的方法+无向边,嗯就是这么简单

#include<bits/stdc++.h>using namespace std;#define M 1010#define inf 0x3f3f3f3fint n,nx,ny,m;int link[M],lx[M],ly[M],slack[M];    int visx[M],visy[M],w[M][M];int casee;int DFS(int x){    visx[x] = 1;    for (int y = 1;y <= ny;y ++)    {        if (visy[y])            continue;        int t = lx[x] + ly[y] - w[x][y];        if (t == 0)              {            visy[y] = 1;            if (link[y] == -1||DFS(link[y]))            {                link[y] = x;                return 1;            }        }        else if (slack[y] > t)              slack[y] = t;    }    return 0;}int KM(){    int i,j;    memset (link,-1,sizeof(link));    memset (ly,0,sizeof(ly));    for (i = 1;i <= nx;i ++)                    for (j = 1,lx[i] = -inf;j <= ny;j ++)            if (w[i][j] > lx[i])                lx[i] = w[i][j];    for (int x = 1;x <= nx;x ++)    {        for (i = 1;i <= ny;i ++)            slack[i] = inf;        while (1)        {            memset (visx,0,sizeof(visx));            memset (visy,0,sizeof(visy));            if (DFS(x))                     break;              int d = inf;            for (i = 1;i <= ny;i ++)                if (!visy[i]&&d > slack[i])                    d = slack[i];            for (i = 1;i <= nx;i ++)                if (visx[i])                    lx[i] -= d;            for (i = 1;i <= ny;i ++)                  if (visy[i])                    ly[i] += d;                else                    slack[i] -= d;        }    }    int cnt=0;     int res = 0;    for (i = 1;i <= ny;i ++)        if (link[i] > -1 && w[link[i]][i] != -inf)            res += w[link[i]][i],cnt++;    if(cnt == n)            return -res;    else    return -1;}int main(){   int t;   freopen("h3435.in","r",stdin);   scanf("%d",&t);   casee = 1;   while(t--)   {        scanf("%d%d",&n,&m);         for(int i = 0;i <= n;i++)        {            for(int j = 0;j <= n;j++)            {                w[i][j] = -inf;            }        }        for(int i = 0;i < m;i++)        {            int a,b,ww;            scanf("%d%d%d",&a,&b,&ww);            if(-w[a][b] > ww) w[a][b]= w[b][a] = -ww;            }        nx = ny = n;        int res = KM();        if(res == -1) printf("Case %d: NO\n",casee++);        else printf("Case %d: %d\n",casee++,res);   }   return 0;}

Ps.做的时候T了三发,查了一大遍也没发现建图有问题,数据范围也没事啊……最后发现是模板用的n^4的……果然太弱。

0 0
原创粉丝点击