HDU-4370 0 or 1
Problem Description
Given a nn matrix Cij (1<=i,j<=n),We want to find a nn matrix Xij (1<=i,j<=n),which is 0 or 1.
Besides,Xij meets the following conditions:
1.X12+X13+...X1n=1
2.X1n+X2n+...Xn-1n=1
3.for each i (1<i<n), satisfies ∑Xki (1<=k<=n)=∑Xij (1<=j<=n).
For example, if n=4,we can get the following equality:
X12+X13+X14=1
X14+X24+X34=1
X12+X22+X32+X42=X21+X22+X23+X24
X13+X23+X33+X43=X31+X32+X33+X34
Now ,we want to know the minimum of ∑Cij*Xij(1<=i,j<=n) you can get.
Hint
For sample, X12=X24=1,all other Xij 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 Cij(0<=Cij<=100000).
Output
For each case, output the minimum of ∑Cij*Xij 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
条件1说明V1出度为1
条件2说明Vn入读为1
条件3说明Vi , (2 <= i <= n-1 ) 入度等于出度
三个条件 <=> 有一条从V1到Vn存在一条路径这样就使得条件1,2,3满足,当然这是充分条件,
还有一种特殊情况,就是V1和Vn都有一条长度大于1的自环,同样能使1,2,3成立。
#include<bits/stdc++.h>
using namespace std;
int dis[303],n,mmp[303][303];
bool in[303];
queue<int>que;
void SPFA(int s,int &loop) {
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(in,0,sizeof(in));
loop=0x3f3f3f3f;
dis[s]=0;
in[s]=1;
que.push(s);
while(!que.empty()) {
int x=que.front();
que.pop();
in[x]=0;
for(int j=1; j<=n; ++j) {
if(j==s&&x!=s) {
loop=min(loop,mmp[x][j]+dis[x]);
}
if(dis[x]+mmp[x][j]<dis[j]) {
dis[j]=dis[x]+mmp[x][j];
if(!in[j]) {
que.push(j);
in[j]=1;
}
}
}
}
}
int main() {
freopen("in.txt","r",stdin);
while((scanf("%d",&n))==1) {
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
scanf("%d",&mmp[i][j]);
int loop1;
//第一遍SPFA求得最短路径和V1的长度大于1的最短自环
SPFA(1,loop1);
int ans=dis[n];
int loop2;
//第二遍求Vn的长度大于1的最短自环
SPFA(n,loop2);
cout<<min(ans,loop1+loop2);
}
return 0;
}