航空路线问题

最大费用最大流。
建图思路:
起点终点能走两次,限流。
用个map存下string与编号的对应关系,输出方案时走那些走过流量的边。

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
const int N=1005,inf=0x3f3f3f3f;
map<string,int> mp;
bool check;
int n,v,S,T;
string s,b,bpw[N];
int k,head[N],ecnt=1,l[N],r[N],from[N],maxflow,mincost,dis[N],opt[2][N],tot[2];
bool inq[N];
struct Edge {
     int to,nxt,val,cost,from;
} e[N*N*2];
void add(int bg,int ed,int val,int cost) {
     e[++ecnt].cost=cost;
     e[ecnt].from=bg;
     e[ecnt].nxt=head[bg];
     e[ecnt].to=ed;
     e[ecnt].val=val;
     head[bg]=ecnt;
}
void insert(int bg,int ed,int val,int cost) {
     cost=-cost;
     add(bg,ed,val,cost);
     add(ed,bg,0,-cost);
}
queue<int>qu;
bool spfa() {
     qu.push(S);
     std::memset(dis,0x3f,sizeof dis);
     dis[S]=0;
     inq[S]=1;
     while(!qu.empty()) {
         int u=qu.front();
         qu.pop();
         inq[u]=0;
         for(int i=head[u],v; i; i=e[i].nxt) {
             v=e[i].to;
             if(dis[v]>dis[u]+e[i].cost&&e[i].val) {
                 dis[v]=dis[u]+e[i].cost;
                 from[v]=i;
                 if(!inq[v]) qu.push(v),inq[v]=1;
             }
         }
     }
     return dis[T]!=inf;
}
void min(int &x,int y) {
     x=x<y?x:y;
}
void mcf() {
     int x=inf,i=from[T];
     while(i) {
         min(x,e[i].val);
         i=from[e[i].from];
     }
     maxflow+=x;
     i=from[T];
     while(i) {
         e[i].val-=x;
         e[i^1].val+=x;
         mincost-=x*e[i].cost;
         i=from[e[i].from];
    }
}
void dfs(int x,int op) {
  opt[op][++tot[op]]=x;
  for(int i=head[x];i;i=e[i].nxt) {
    int v=e[i].to;
    if(i&1) continue;
    if(e[i^1].val) {
      e[i^1].val--;
      dfs(v,op);
      return;
    }
  }
}
int main() {
   scanf("%d%d",&n,&v);
   S=0,T=2*n+1;
   for(int i=1;i<=n;i++) cin>>s,mp[s]=i,bpw[i]=s;
   insert(S,1,2,0);
   insert(n<<1,T,2,0);
   insert(1,1+n,2,1);
   insert(n,n+n,2,1);
   for(int i=2;i<n;i++)
     insert(i,i+n,1,1);
   for(int i=1;i<=v;i++){
     cin>>s>>b;
     int st=mp[s],ed=mp[b];
     if(st<ed)insert(st+n,ed,1,0);
     else insert(ed+n,st,inf,0);
   }
   while(spfa()) mcf();
   if(!maxflow) {puts("No Solution!");return 0;}
   if(maxflow==1) {cout<<2<<endl<<bpw[1]<<endl<<bpw[n]<<endl<<bpw[1];return 0;}
   cout<<mincost-2<<endl;
   dfs(1,0),dfs(1,1);
   bool flag=0;
   for(int i=1;i<=tot[0];i++) if(opt[0][i]>=1&&opt[0][i]<=n) cout<<bpw[opt[0][i]]<<endl;
   for(int i=tot[1];i;i--) {
     if(opt[1][i]>=1&&opt[1][i]<=n) {
      if(!flag) {
        flag=1;
        continue;
      }
      cout<<bpw[opt[1][i]]<<endl;
     }
   }
   return 0;
}
posted @ 2018-07-17 20:43  SWHsz  阅读(129)  评论(0编辑  收藏  举报