• 网络流24题——航空路线问题(最长不相交路径)


    链接:https://www.oj.swust.edu.cn/oj/problem/show/1746

    题意:给定无向图,求一条从s到t再到s的最长路径,除s外每个点最多经过一次。

    分析:实际上相当于求两条从s到t的路径,两条路径互不相交且长度和最大。先拆点,把每个点拆成X和Y,连一条容量为1、费用为-1的边,再求一次最小费用最大流。最大流不为2时无解。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<vector>
      5 #include<queue>
      6 #include<stack>
      7 #include<map>
      8 #include<string>
      9 using namespace std;
     10 typedef long long ll;
     11 const int maxn=205,INF=1e9;
     12 int n,v;
     13 map<string,int> city;
     14 string name[maxn];
     15 struct Edge{
     16     int from,to,cap,flow,cost;
     17     Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),flow(f),cost(w){}
     18 };
     19 struct MCMF{
     20     int n,s,t;
     21     vector<Edge> edges;
     22     vector<int> G[maxn];
     23     int inq[maxn],d[maxn],p[maxn],a[maxn];
     24     ll flow,cost;
     25     void init(int n){
     26         this->n=n;
     27         flow=0,cost=0;
     28         for(int i=0;i<n;i++)G[i].clear();
     29         edges.clear();
     30     }
     31 
     32     void AddEdge(int from,int to,int cap,int cost){
     33         edges.push_back(Edge(from,to,cap,0,cost));
     34         edges.push_back(Edge(to,from,0,0,-cost));
     35         G[from].push_back(edges.size()-2);
     36         G[to].push_back(edges.size()-1);
     37     }
     38 
     39     bool spfa(int s,int t){
     40         this->s=s;this->t=t;
     41         for(int i=0;i<n;i++)d[i]=INF;
     42         memset(inq,0,sizeof(inq));
     43         d[s]=0;inq[s]=1;p[s]=0;a[s]=INF;
     44         queue<int>Q;
     45         Q.push(s);
     46         while(!Q.empty()){
     47             int u=Q.front();Q.pop();
     48             inq[u]=0;
     49             for(int i=0;i<G[u].size();i++){
     50                 Edge& e=edges[G[u][i]];
     51                 if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
     52                     d[e.to]=d[u]+e.cost;
     53                     p[e.to]=G[u][i];
     54                     a[e.to]=min(a[u],e.cap-e.flow);
     55                     if(!inq[e.to]){Q.push(e.to);inq[e.to]=1;}
     56                 }
     57             }
     58         }
     59         if(d[t]==INF)return false;
     60         flow+=a[t];cost+=d[t]*a[t];
     61         int u=t;
     62         while(u!=s){
     63             edges[p[u]].flow+=a[t];
     64             edges[p[u]^1].flow-=a[t];
     65             u=edges[p[u]].from;
     66         }
     67         return true;
     68     }
     69     ll Mincost(int s,int t){
     70         while(spfa(s,t));
     71         return cost;
     72     }
     73     void Print(int n){
     74         int have[maxn];
     75         memset(have,0,sizeof(have));
     76         cout<<name[1]<<endl;
     77         int u=s+n;
     78         while(u!=t+n){
     79             for(int i=0;i<G[u].size();i++){
     80                 Edge &e=edges[G[u][i]];
     81                 if(e.flow>=1&&have[e.to]==0){
     82                     have[e.to]=1;
     83                     cout<<name[e.to]<<endl;
     84                     u=e.to+n;break;
     85                 }
     86             }
     87             if(u==s+n)break;
     88         }
     89         u=n;
     90         while(u!=s){
     91             for(int i=0;i<G[u].size();i++){
     92                 Edge &e=edges[G[u][i]^1];
     93                 if(e.flow>=1&&have[e.from-n]==0){
     94                     have[e.from-n]=1;
     95                     cout<<name[e.from-n]<<endl;
     96                     u=e.from-n;break;
     97                 }
     98             }
     99             if(u==n)break;
    100         }
    101     }
    102 }mcmf;
    103 int main(){
    104 //    freopen("e:\in.txt","r",stdin);
    105     string s,t;
    106     scanf("%d%d",&n,&v);
    107     mcmf.init(2*n);
    108     mcmf.AddEdge(1,1+n,2,0);
    109     for(int i=2;i<n;i++)mcmf.AddEdge(i,i+n,1,-1);
    110     for(int i=1;i<=n;i++){
    111         cin>>s;
    112         city[s]=i;
    113         name[i]=s;
    114     }
    115     for(int i=0;i<v;i++){
    116         cin>>s>>t;
    117         mcmf.AddEdge(city[s]+n,city[t],INF,0);
    118     }
    119     int ans=2-mcmf.Mincost(1,n);
    120     if(mcmf.flow!=2){
    121         printf("No Solution!
    ");
    122     }else{
    123         printf("%d
    ",ans);
    124         mcmf.Print(n);
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    微信公众号开发问题总结(坑)
    map 取值报空指针,明明值存在
    关于客户端Socket连接服务端,客户端只有在服务端关闭后才收到数据的问题
    关于Spine动画,关于cocosCreator
    cocsoCreator实现镜头跟随节点移动
    cocos节点添加Touch监听代码
    使用git管理你的代码,使用git托管代码至gitee
    关于ccoosCreator里的物理系统
    Python Scrapy 爬虫简单教程
    quasar 参考文档
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7448277.html
Copyright © 2020-2023  润新知