0 or 1 HDU - 4370 (思维+最短路)
作者:互联网
Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij(1<=i,j<=n),which is 0 or 1.
Besides,X ij meets the following conditions:
1.X 12+X 13+...X 1n=1
2.X 1n+X 2n+...X n-1n=1
3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n).
For example, if n=4,we can get the following equality:
X 12+X 13+X 14=1
X 14+X 24+X 34=1
X 12+X 22+X 32+X 42=X 21+X 22+X 23+X 24
X 13+X 23+X 33+X 43=X 31+X 32+X 33+X 34
Now ,we want to know the minimum of ∑C ij*X ij(1<=i,j<=n) you can get.
Hint
For sample, X 12=X 24=1,all other X ij is 0.
Besides,X ij meets the following conditions:
1.X 12+X 13+...X 1n=1
2.X 1n+X 2n+...X n-1n=1
3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n).
For example, if n=4,we can get the following equality:
X 12+X 13+X 14=1
X 14+X 24+X 34=1
X 12+X 22+X 32+X 42=X 21+X 22+X 23+X 24
X 13+X 23+X 33+X 43=X 31+X 32+X 33+X 34
Now ,we want to know the minimum of ∑C ij*X ij(1<=i,j<=n) you can get.
Hint
For sample, X 12=X 24=1,all other X ij is 0.
InputThe input consists of multiple test cases (less than 35 case).
For each test case ,the first line contains one integer n (1<n<=300).
The next n lines, for each lines, each of which contains n integers, illustrating the matrix C, The j-th integer on i-th line is C ij(0<=C ij<=100000).OutputFor each case, output the minimum of ∑C ij*X ij you can get.
Sample Input
4 1 2 4 10 2 0 1 1 2 2 0 5 6 3 1 2
Sample Output
3
分析:学到了如何求从一个点到这个点途径至少一个点的最短环。
将条件转化为图论最短路径问题,Xij 转化为边 i→j 的权值,那么对应关系为:
- 表示点 1 的出度为 1
- 表示点 n 的入度为 1
- 除了点 1 和点 n 外的其他点出入度相等
求解的问题转化为点 1 到点 n 的一条最短路径。
其实还有一种情况,那就是可以从点 1 出发到达其他点然后又回到点 1 形成一个环,同样也可以从点 n 出发回到点 n。这样也是符合条件的,答案为从 1 出发的最小权值环和从 n 出发的最小权值环之和。
答案为两种情况的最小值
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 int n; 5 int g[400][400]; 6 int dis[400], inq[400]; 7 8 void spfa(int x) 9 { 10 queue<int> q; 11 memset(inq, 0, sizeof(inq)); 12 for (int i = 1; i <= n; i++) 13 { 14 if (i == x) 15 dis[i] = inf; 16 else 17 { 18 dis[i] = g[x][i]; 19 q.push(i); 20 inq[i] = true; 21 } 22 } 23 while (!q.empty()) 24 { 25 int u = q.front(); q.pop(); 26 inq[u] = false; 27 for (int i = 1; i <= n; i++) 28 if (dis[i] > dis[u] + g[u][i]) 29 { 30 dis[i] = dis[u] + g[u][i]; 31 if (!inq[i]) 32 q.push(i), inq[i]; 33 } 34 } 35 } 36 37 38 int main() 39 { 40 while (cin >> n) 41 { 42 for (int i = 1; i <= n; i++) 43 for (int j = 1; j <= n; j++) 44 scanf("%d", &g[i][j]); 45 spfa(1); 46 int ans = dis[n]; 47 int c1 = dis[1]; 48 spfa(n); 49 int c2 = dis[n]; 50 cout << min(ans, c1 + c2) << endl; 51 } 52 }
标签:HDU,12,int,短路,inq,ij,each,4370,dis 来源: https://www.cnblogs.com/liuwenhan/p/11437033.html