hdu4370 0 or 1 最短路

来源:互联网 发布:小米服务号是什么软件 编辑:程序博客网 时间:2024/05/17 05:58
Problem Description
Given a n*n matrix Cij (1<=i,j<=n),We want to find a n*n 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.
Sample Input
41 2 4 102 0 1 12 2 0 56 3 1 2
 

Sample Output
3

在比赛的时候我的思路是X矩阵只可能是0 or 1,所以分为三种情况,分别求出最小值,然后再取最小值。

但是后来发现还是有少情况的时候。反正就是没往图论的方向想,赛后看解题报告,才恍然大悟。

这道题关键在于看懂题的隐含意思。

三个条件可以理解为:第一个点出度为1,最后一个点入度为0. 据说在比赛时的数据水了,没有考虑有环的情况。

因为第一个点有可能有入度,最后一个点也可能有出度。所以还可以看做是第一个点的一个环和最后一个点的一个环的和。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxint=1e7;const int mm=400;const int mn=1111111;int dis[mm],head[mm],q[mm],vis[mm];int c[mm][mm];int n,edge;int ver[mn],next[mn],cost[mn];void addedge(int u,int v,int c){    ver[edge]=v,cost[edge]=c,next[edge]=head[u],head[u]=edge++;}int spfa(int src){    int i,u,v,l,r=0,tmp,cir;    for(i=0;i<=n;i++)    dis[i]=maxint;    dis[q[r++]=src]=0;    vis[src]=1;    cir=maxint;    for(l=0;l!=r;(++l>mm)?l=0:l)//第三个条件非常重要,这个也给忘记了,呜呜。。。。        for(i=head[u=q[l]],vis[u]=0;i>=0;i=next[i])        {            if(ver[i]==src&&dis[u]+cost[i]<cir) cir=dis[u]+cost[i];            if(dis[v=ver[i]]>(tmp=dis[u]+cost[i]))            {                dis[v]=tmp;                if(vis[v])  continue;                vis[q[r++]=v]=1;                if(r>=mm)   r=0;            }        }    return cir;}int main(){    int i,j,tot,ans;    while(~scanf("%d",&n))    {        for(i=1;i<=n;i++)            for(j=1;j<=n;j++)                scanf("%d",&c[i][j]);        edge=0;        memset(head,-1,sizeof(head));//忘记初始化head了,找了好长时间。。。        memset(vis,0,sizeof(vis));        for(i=1;i<=n;i++)            for(j=1;j<=n;j++)            if(i!=j)                addedge(i,j,c[i][j]);        ans=spfa(1);        tot=dis[n];        int ans1=spfa(n);        ans=min(tot,ans+ans1);        printf("%d\n",ans);    }    return 0;}


原创粉丝点击