USACO Section 5.4 Canada Tour

来源:互联网 发布:武汉美工培训班学费 编辑:程序博客网 时间:2024/05/22 23:19

题意:

有向图上从起点到终点的两条路径的距离最大值是多少


思路:

费用流较容易理解(点拆成边  除了起点终点流量2费用0以外其他流量1费用1) 求最大费用最大流

DP思想

利用枚举最远点来保证两条路没有公共点  f[i][j]表示一个人在i另一个人在j时候的总距离  g[i][j]表示f[i][j]状态是不是出现过

首先枚举i表示现在可达最远点  然后n^2枚举所有状态  如果g[x][y]=1  则让x或y走到i(前提当然是有路)  这样就可以避免重复(即现在枚举到的这个点只让一个人走过)


代码:

/*ID: housera1PROG: tourLANG: C++*/#include<cstdio>#include<cstring>#include<algorithm>#include<map>#include<string>#include<iostream>using namespace std;#define N 110int n,m,ans;int maz[N][N],f[N][N],g[N][N];map<string,int> id;int main(){    int Debug=0;    if(!Debug)    {        freopen("tour.in","r",stdin);        freopen("tour.out","w",stdout);    }    int i,j,k;    string str,st;    scanf("%d%d",&n,&m);    for(i=1;i<=n;i++)    {        cin>>str;        id[str]=i;    }    for(i=1;i<=m;i++)    {        cin>>str>>st;        j=id[str];        k=id[st];        if(j>k) swap(j,k);        maz[j][k]=maz[k][j]=1;    }    g[1][1]=1; f[1][1]=1;    for(i=2;i<=n;i++)    {        for(j=1;j<i;j++)        {            for(k=1;k<i;k++)            {                if(g[j][k])                {                    if(maz[j][i]&&f[i][k]<f[j][k]+1)                    {                        f[i][k]=f[j][k]+1;                        g[i][k]=1;                        if(i==n&&f[i][k]>ans&&maz[k][n]) ans=f[i][k];                    }                    if(maz[k][i]&&f[j][i]<f[j][k]+1)                    {                        f[j][i]=f[j][k]+1;                        g[j][i]=1;                        if(i==n&&f[j][i]>ans&&maz[j][n]) ans=f[j][i];                    }                }            }        }    }    printf("%d\n",max(ans,1));    return 0;}


0 0
原创粉丝点击