0 or 1 HDU

来源:互联网 发布:php 项目经验 模板 编辑:程序博客网 时间:2024/06/01 22:40
 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=12.X 1n+X 2n+...X n-1n=13.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=1X 14+X 24+X 34=1X 12+X 22+X 32+X 42=X 21+X 22+X 23+X 24X 13+X 23+X 33+X 43=X 31+X 32+X 33+X 34Now ,we want to know the minimum of ∑C ij*X ij(1<=i,j<=n) you can get.Hint

题意:表示1号点出度为1,表示n号点入度为1,表示k( 1 < k < n )号点出度等于入度。∑Cij*Xij(1<=i,j<=n),很明显,这是某个路径的花费,而路径的含义可以有以下两种:
一:1号点到n号点的花费
二:1号点经过其它点成环,n号点经过其它点成环,这两个环的花费之和
于是,就变成了一道简单的最短路问题
关于环花费的算法,可以改进spfa算法,初始化dis[start] = INF,且一开始让源点之外的点入队
4
1 2 4 10
2 0 1 1
2 2 0 5
6 3 1 2

Sample Output

3

Input
The input consists of multiple test cases (less than 35 case).
For each test case ,the first line contains one integer n (1

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<stack>#define INF 0x3f3f3f3fusing namespace std;int cost[550][550];int dis[500],vis[500];int n;int min(int a,int b){   return  a < b ? a : b;}void spfa(int start){    stack<int>Q;    memset(vis,0,sizeof(vis));    for(int i=1;i<=n;i++)    {       dis[i] = cost[start][i];       if(i!=start)       {          Q.push(i);          vis[i] = 1;       }    }    dis[start] = INF;    while(!Q.empty())    {       int x = Q.top();       Q.pop();       vis[x] = 0;       for(int y = 1;y<=n;y++)       {          if(x==y) continue;          if(dis[x]+cost[x][y]<dis[y])          {             dis[y] = dis[x]+cost[x][y];             if(!vis[y])             {                vis[y] = 1;                Q.push(y);             }          }       }    }}int main(){    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)        {           for(int j=1;j<=n;j++)           {               scanf("%d",&cost[i][j]);           }        }        int ans,c1,cn;        spfa(1);        ans = dis[n];        c1  = dis[1];//从1到1        spfa(n);        cn = dis[n];//从n到n        ans = min(ans,c1+cn);        printf("%d\n",ans);    }    return 0;}