HDU 4370 0 or 1

0 or 1

Time Limit: 2000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 4370
64-bit integer IO format: %I64d      Java class name: Main
Given a n*n matrix Cij (1<=i,j<=n),We want to find a n*n matrix $X_{ij} (1<=i,j<=n)$,which is 0 or 1.

Besides,Xij 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 \[\sum{X_{ki}} (1<=k<=n)=\sum{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 $\sum{C_{ij}\times X_{ij}}(1<=i,j<=n)$ you can get.
Hint

For sample, $X_{12}=X_{24}=1$,all other $X_{ij}$ is 0.
 

Input

The 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<=Cij<=100000)$.
 

Output

For each case, output the minimum of $\sum{C_{ij}\times 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

Source

 
解题:居然可以转化为最短路 惊呆了。。
 
观察等式我们可以发现 1的出度为1 n的入度为1 其余的入度等于出度
 
01矩阵 2-n-1行 行和等于列和
 
可以求从1到n的最短路,这个还可以理解,那个1到其他再到1 n到其他再到n 暂时我没法理解
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 #include <cstring>
 5 using namespace std;
 6 const int maxn = 310;
 7 int n,mp[maxn][maxn],d[maxn];
 8 int spfa(int s,int t,int &val) {
 9     queue<int>q;
10     bool inq[maxn] = {false};
11     memset(d,0x3f,sizeof d);
12     q.push(s);
13     d[s] = 0;
14     val = INT_MAX;
15     while(!q.empty()) {
16         int u = q.front();
17         q.pop();
18         inq[u] = false;
19         for(int i = 0; i < n; ++i) {
20             if(u != s && i == s) val = min(val,d[u]+mp[u][i]);
21             if(d[i] > d[u] + mp[u][i]) {
22                 d[i] = d[u] + mp[u][i];
23                 if(!inq[i]) {
24                     inq[i] = true;
25                     q.push(i);
26                 }
27             }
28         }
29     }
30     return d[t];
31 }
32 int main() {
33     while(~scanf("%d",&n)) {
34         for(int i = 0; i < n; ++i)
35             for(int j = 0; j < n; ++j)
36                 scanf("%d",mp[i]+j);
37         int a,b;
38         int ret = spfa(0,n-1,a);
39         spfa(n-1,0,b);
40         printf("%d\n",min(a+b,ret));
41     }
42     return 0;
43 }
View Code

 

posted @ 2015-07-22 21:55  狂徒归来  阅读(229)  评论(0编辑  收藏  举报