zoukankan      html  css  js  c++  java
  • LA 2957 最大流,最短时间,输出路径

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=159&page=show_problem&problem=958

    题意:n个星球,用最短的时间把k个超级计算机从s运到t;

    其中,每个隧道是双向的,一个隧道里面只能有一个飞船在使用,一个飞船上只有一台计算机。

    分析:

    一个隧道只能给一个飞船用,那么假设需要t天,那么可以这样建图:

    u结点,拆成t+1个,分别是 u0,u1,u2,...,ut;

    u0是u的初始状态,ui是u在第i天的状态,那么建图就是:

    a结点到b结点,ai 到 bi+1 一条容量为1的边,bi 到 ai+1 的容量为1的一条边。

    对于每个结点,都有ui到ui+1 的容量是无穷大,因为可以停留。

    一天一天增加结点,终点也发生变化,流量直到为k,就结束了。

    然后输出路径:

    遍历原图的上的每一条边,注意edges是残余网络,idx+=2;这才加了一条边。

    问题问的路径是(A,B)编号为A的飞机,到达行星 B,行星B就是有流量的那一条边都后面那个结点。那么,编号A怎么求呢?

    可以遍历一下这k个飞机,如果 j 所在的位置location[j] = a[i] 的话,就ok了。

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 const int maxn = 5000+10;
      6 const int INF = 0x3f3f3f3f;
      7 
      8 struct Edge{
      9     int from,to,cap,flow;
     10 };
     11 
     12 bool operator < (const Edge& a,const Edge& b) {
     13     return a.from < b.from||(a.from==b.from&&a.to<b.to);
     14 }
     15 
     16 struct Dinic {
     17     int n,m,s,t;
     18     vector<Edge> edges;
     19     vector<int> G[maxn];
     20     bool vis[maxn];
     21     int d[maxn];
     22     int cur[maxn];
     23 
     24     void init() {
     25         edges.clear();
     26     }
     27 
     28     void clearNodes(int a,int b) {
     29         for(int i=a;i<=b;i++)
     30             G[i].clear();
     31     }
     32 
     33     void AddEdge(int from,int to,int cap) {
     34         edges.push_back((Edge){from,to,cap,0});
     35         edges.push_back((Edge){to,from,0,0});
     36         m = edges.size();
     37         G[from].push_back(m-2);
     38         G[to].push_back(m-1);
     39     }
     40 
     41     bool BFS() {
     42         memset(vis,0,sizeof(vis));
     43         queue<int> Q;
     44         Q.push(s);
     45         vis[s] = 1;
     46         d[s] = 0;
     47         while(!Q.empty()) {
     48             int x = Q.front();  Q.pop();
     49             for(int i=0;i<G[x].size();i++) {
     50                 Edge& e = edges[G[x][i]];
     51                 if(!vis[e.to]&&e.cap>e.flow) {
     52                     vis[e.to] = 1;
     53                     d[e.to] = d[x] + 1;
     54                     Q.push(e.to);
     55                 }
     56             }
     57         }
     58         return vis[t];
     59     }
     60 
     61     int DFS(int x,int a) {
     62         if(x==t||a==0) return a;
     63         int flow = 0,f;
     64         for(int& i=cur[x];i<G[x].size();i++) {
     65             Edge& e = edges[G[x][i]];
     66             if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) {
     67                 e.flow +=f;
     68                 edges[G[x][i]^1].flow-=f;
     69                 flow+=f;
     70                 a-=f;
     71                 if(a==0) break;
     72             }
     73         }
     74         return flow;
     75     }
     76 
     77     int Maxflow(int s,int t,int limit) {
     78         this->s = s;
     79         this->t = t;
     80         int flow = 0;
     81         while(BFS()) {
     82             memset(cur,0,sizeof(cur));
     83             flow +=DFS(s,limit-flow);
     84             if(flow==limit) break;
     85         }
     86         return flow;
     87     }
     88 };
     89 
     90 Dinic g;
     91 
     92 int main()
     93 {
     94     int n,m,k,s,t;
     95     int u[maxn],v[maxn];
     96 
     97     while(~scanf("%d%d%d%d%d",&n,&m,&k,&s,&t)) {
     98         for(int i=0;i<m;i++) {
     99             scanf("%d%d",&u[i],&v[i]);
    100         }
    101         g.init();
    102         int day = 1;
    103         g.clearNodes(0,n-1);
    104         int flow = 0;
    105         for(;;) {
    106             g.clearNodes(day*n,day*n+n-1);
    107             for(int i=0;i<n;i++)
    108                 g.AddEdge((day-1)*n+i,day*n+i,INF);
    109             for(int i=0;i<m;i++) {
    110                 g.AddEdge((day-1)*n+u[i]-1,day*n+v[i]-1,1);
    111                 g.AddEdge((day-1)*n+v[i]-1,day*n+u[i]-1,1);
    112             }
    113             flow+=g.Maxflow(s-1,day*n+t-1,k-flow);
    114             if(flow==k) break;
    115             day++;
    116         }
    117 
    118         printf("%d
    ",day);
    119 
    120         int idx = 0;
    121         vector<int> location(k,s);
    122 
    123         for(int d=1;d<=day;d++) {
    124             idx +=n*2;
    125             vector<int> moved(k,0);
    126             vector<int> a,b;
    127 
    128             for(int i=0;i<m;i++) {
    129                 int f1 = g.edges[idx].flow; idx+=2;
    130                 int f2 = g.edges[idx].flow; idx+=2;
    131                 if(f1==1&&f2==0) {
    132                     a.push_back(u[i]);
    133                     b.push_back(v[i]);
    134                 }
    135                 if(f1==0&&f2==1) {
    136                     a.push_back(v[i]);
    137                     b.push_back(u[i]);
    138                 }
    139             }
    140 
    141             printf("%d",a.size());
    142             for(int i=0;i<a.size();i++) {
    143                 for(int j=0;j<k;j++) {  //找到具体是哪一个飞船
    144                     if(!moved[j]&&location[j]==a[i]) {
    145                         printf(" %d %d",j+1,b[i]);
    146                         moved[j] = 1;
    147                         location[j] = b[i];
    148                         break;
    149                     }
    150                 }
    151             }
    152             printf("
    ");
    153 
    154         }
    155 
    156     }
    157 
    158     return 0;
    159 }
  • 相关阅读:
    nginx default setting
    ubuntu dotnet core run 十月第一弹
    vwmare 十月第 1 弹
    学习 lind 语 里的一些组件使用。
    学习  解决用户验证、单点登录、api访问控制的开源框架 的 十月 第一弹:
    学习 lind api 十月 第5弹
    Data for the People: How to Make Our Post-Privacy Economy Work for You
    iframe高度的自适应
    dtree在ie6下点击页面报错
    前台页面分页对总页数的判断
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6539460.html
Copyright © 2011-2022 走看看