码迷,mamicode.com
首页 > 其他好文 > 详细

网络流24题 洛谷 2770 航空路线问题

时间:2018-04-29 12:01:50      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:close   spfa   分享图片   ++   pac   inpu   网络   opened   ==   

注意好处理读入和读出一定用cin!

技术分享图片
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>

#define MX 80001
#define oo 12312312
#define S 1
#define T (n<<1)

using namespace std;

typedef struct edge_t
{
    int u,v,c,w;
}edge;
edge e[MX];
int fst[MX],nxt[MX],lnum;
int n,m;
map<string,int>mp;
string name[1001];

void addeg(int nu,int nv,int nc,int nw)
{
    nxt[++lnum]=fst[nu];
    fst[nu]=lnum;
    e[lnum]=(edge){nu,nv,nc,nw};
}

void input()
{
    string str1,str2;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        cin>>str1;
        mp[str1]=i;
        name[i]=str1;
        addeg(i,n+i,1,1);
        addeg(n+i,i,0,-1);
    }
    for(int i=1;i<=m;i++)
    {
        cin>>str1>>str2;
        addeg(mp[str1]+n,mp[str2],1,1),addeg(mp[str2],mp[str1]+n,0,-1);
    }
    addeg(1,n+1,1,1),addeg(n+1,1,0,-1);
    addeg(n,n*2,1,1),addeg(n*2,n,0,-1);
}

void init()
{
    memset(fst,0xff,sizeof(fst));
    lnum=-1;
}

int q[MX],pre[MX],dis[MX],inq[MX];
int spfa(int *flow,int *cost)
{
    int h=0,t=1,x,y;
    memset(dis,0x9f,sizeof(dis));
    memset(inq,0,sizeof(inq));
    memset(pre,0,sizeof(pre));
    q[++h]=S;
    dis[S]=0;
    pre[S]--;
    inq[S]=1;
    while(h>=t)
    {
        x=q[(t++)%MX];
        inq[x]=0;
        for(int i=fst[x];i!=-1;i=nxt[i])
        {
            y=e[i].v;
            if(e[i].c&&dis[y]<dis[x]+e[i].w)
            {
                dis[y]=dis[x]+e[i].w;
                pre[y]=i;
                if(!inq[y])
                {
                    q[(++h)%MX]=y;
                    inq[y]=1;
                }
            }
        }
    }
    if(dis[T]<0)return 0;
    int now=pre[T],mxf=+oo,cst=0;
    while(now!=-1)
    {
        mxf=min(mxf,e[now].c);
        cst+=e[now].w;
        now=pre[e[now].u];
    }
    now=pre[T];
    while(now!=-1)
    {
        e[now].c-=mxf;
        e[now^1].c+=mxf;
        now=pre[e[now].u];
    }
    *flow+=mxf;
    *cost+=cst*mxf;
    return 1;
}

int ans[1001];int anum=0;
void out(int x)
{
    ans[++anum]=x;
    for(int i=fst[x];i!=-1;i=nxt[i])
        if(e[i].c==0&&e[i].w>=0)
        {
            out(e[i].v);
            e[i].c=1;
            return;
        }
}

int main()
{
    int cost=0,flow=0;
    init();
    input();
    while(spfa(&flow,&cost));//求最大流
    if(flow==0){printf("No Solution!\n");return 0;}//如果无解
    else if(flow==1){cout<<2<<endl<<name[1]<<endl<<name[n]<<endl<<name[1]<<endl;return 0;}//如果只有一条合法航线(即只能在1,n之间往返)
    else//否则两条合法航线
    {
        printf("%d\n",cost/2-1);
        out(S);//寻找经过的点
        for(int i=1;i<=anum;i++)if(ans[i]<=n)cout<<name[ans[i]]<<endl;
        anum=0;
        out(S);
        for(int i=anum-2;i>=1;i--)if(ans[i]<=n)cout<<name[ans[i]]<<endl;
    }
    return 0;
}
Ans

 

网络流24题 洛谷 2770 航空路线问题

标签:close   spfa   分享图片   ++   pac   inpu   网络   opened   ==   

原文地址:https://www.cnblogs.com/horsepower2001/p/8970426.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!