这题可以学到:以后求有向图中的环 , 可以用二分图来求。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <queue> using namespace std; #define maxn 120 #define INF 0xffffff int grap[maxn][maxn]; int n; int cx[maxn] , cy[maxn]; int lx[maxn] , ly[maxn]; int pre[maxn]; int s[maxn] , t[maxn]; int slack[maxn]; void init() { memset(grap , -1 , sizeof(grap)); memset(cx , -1 , sizeof(cx)); memset(cy , -1 , sizeof(cy)); } int findpath(int u) { s[u] = 1; for(int i = 1; i <= n; i++) { if(grap[u][i] != -1) { if(lx[u]+ly[i]==grap[u][i] && !t[i]) { t[i] = 1; if(cy[i] == -1 || findpath(cy[i])) { cy[i] = u; cx[u] = grap[u][i]; return 1; } } else slack[i] = min(slack[i] , grap[u][i]-lx[u]-ly[i]); } } return 0; } int match() { int i , j; for(i = 1; i <= n; i++) { ly[i] = 0; lx[i] = INF; for(j = 1; j <= n; j++) if(grap[i][j] != -1) lx[i] = min(lx[i] , grap[i][j]); } for(i = 1; i <= n; i++) { for(; ;) { for(j = 1; j <= n; j++) { s[j]=t[j] = 0; slack[j] = INF; } if(findpath(i)) break; int a = INF; for(j = 1; j <= n; j++) if(!t[j]) a = min(a , slack[j]); if(a == INF) return -1; for(j = 1; j <= n; j++) { if(s[j]) lx[j] += a; if(t[j]) ly[j] -= a; } } } return 1; } int main() { while(scanf("%d" , &n) && n) { init(); int i , j , x , y; for(i = 1; i <= n; i++) { for(; ;) { scanf("%d" , &x); if(x == 0) break; scanf("%d" , &y); if(grap[i][x] == -1 || grap[i][x] > y) grap[i][x] = y; } } x = match(); if(x == -1) { cout<<"N"<<endl; } else { x = 0; for(i = 1; i <= n; i++) x += cx[i]; cout<<x<<endl; } } return 0; }
LA 3353 Optimal Bus Route Design 二分匹配和有向图中的环,布布扣,bubuko.com
LA 3353 Optimal Bus Route Design 二分匹配和有向图中的环
原文:http://blog.csdn.net/zengchen__acmer/article/details/25281105