hdu3488解题报告

来源:互联网 发布:田井中彩智 知乎 编辑:程序博客网 时间:2024/05/16 01:41

题意:一个王国里有很多个城市,这些城市之间有很多单向的路连接起来,并且存在一个或者多个回路,那么这里求出走几个回路之后访问所有的城市的最小路径距离,

分析:这里我第一次想到最短路,但是对于有回路这个不知道怎么处理,后来看了别人的解题报告才知道KM匹配,但是看到KM之后就自己想...想了很久....还是不知道回路这个地方怎么匹配......其实应该这样来想....总共有N个城市....如果是要形成回路..那么就是环,那么每一个城市都要和指向的城市匹配一次,也要被一个城市指向自己匹配一次...那么匹配的时候我们把所有的N个城市分成两拨,对于每一个城市都匹配一次就得到了一个完全匹配(既每个点都匹配一次,也就是每一个城市匹配一次、被匹配一次).....那么还有一个地方要注意的是:这里有重边...我们应该选择小的边更新

那么上马:

// 78MS 396K #include<stdio.h>#include<string.h>#define MAX 7#define INF 1<<30-1int w[MAX][MAX];int link[MAX],lx[MAX],ly[MAX],slar[MAX];bool visx[MAX],visy[MAX];int N,M;bool dfs(int u){visx[u] = true ;for(int v = 1; v <= N ; v ++){if(visy[v]) continue; //int t = lx[u] + ly[v] -w[u][v];if(t == 0){visy[v] = true;if(link[v] == -1 || dfs(link[v])){link[v] = u;return true;}}elseslar[v] =slar[v] > t ? t:slar[v];}return false;}int KM(){int i,j;memset(ly,0,sizeof(ly));memset(link,-1,sizeof(link));for(i = 1; i <= N; i ++){lx[i] = -INF;for(j = 1; j <= N; j ++)lx[i] = lx[i] > w[i][j] ? lx[i] : w[i][j];}for(int u = 1; u <= N ; u ++){for(i = 1; i <= N; i ++) slar[i] = INF;while(1){memset(visx,false, sizeof(visx));memset(visy,false,sizeof(visy));if(dfs(u)) break;int d=INF;for(i = 1 ;i <= N; i ++)if(!visy[i])  d = d > slar[i] ? slar[i] : d;for(i =1 ; i <= N; i ++)if(visx[i]) lx[i] -= d;for(i =1 ;i <= N; i ++)if(visy[i]) ly[i] += d;else   slar[i] -= d;}}int ans=0;for(i = 1; i <= N; i ++)ans+=w[link[i]][i];return ans;}int main(){int i,j;int T;scanf("%d",&T);while(T--){int a,b,c;scanf("%d%d",&N,&M);for(i = 1 ; i <= N ; i ++)for(j = 1; j <= N ;j ++)w[i][j] = -INF;for(i = 0; i < M; i ++){scanf("%d%d%d",&a,&b,&c);w[a][b]=w[a][b] > -c ? w[a][b] : -c; //重边选择}printf("%d\n",-KM());}return 0;}


原创粉丝点击