zoukankan      html  css  js  c++  java
  • 网络流24题——星际转移问题(思维)

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

    分析:这题最难的地方在于飞船的周期性,不同时间图不一样。。。考虑枚举天数,记Xn,m为第n天的第m个点,从Xn,m向Xn+1,l连一条边,m,l之间这一天有飞船,容量为飞船容量,然后从Xn,m向Xn+1,m连一条容量为无穷大,求从地球到月亮的最大流,当最大流>=k停止。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<vector>
      4 #include<queue>
      5 #include<cstring>
      6 using namespace std;
      7 const int maxn=1e3+5,INF=1e9;
      8 struct Edge{
      9     int from,to,cap,flow;
     10     Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
     11 };
     12 struct ISAP{
     13     int n,s,t,flow;
     14     vector<Edge> edges;
     15     vector<int> G[maxn];
     16     bool vis[maxn];
     17     int d[maxn],cur[maxn],p[maxn],num[maxn];
     18 
     19     void init(int n){
     20         this->n=n;
     21         flow=0;
     22         edges.clear();
     23         for(int i=0;i<n;i++)G[i].clear();
     24     }
     25 
     26     void AddEdge(int from,int to,int cap){
     27         edges.push_back(Edge(from,to,cap,0));
     28         edges.push_back(Edge(to,from,0,0));
     29         G[from].push_back(edges.size()-2);
     30         G[to].push_back(edges.size()-1);
     31     }
     32 
     33     void BFS(){
     34         memset(vis,0,sizeof(vis));
     35         queue<int>Q;
     36         Q.push(t);
     37         d[t]=0;vis[t]=1;
     38         while(!Q.empty()){
     39             int x=Q.front();Q.pop();
     40             for(int i=0;i<G[x].size();i++){
     41                 Edge &e=edges[G[x][i]^1];
     42                 if(e.flow==e.cap)continue;
     43                 if(!vis[e.from]){
     44                     vis[e.from]=1;
     45                     d[e.from]=d[x]+1;
     46                     Q.push(e.from);
     47                 }
     48             }
     49         }
     50     }
     51 
     52     int Augmemt(){
     53         int x=t,a=INF;
     54         while(x!=s){
     55             Edge &e=edges[p[x]];
     56             a=min(a,e.cap-e.flow);
     57             x=edges[p[x]].from;
     58         }
     59         x=t;
     60         while(x!=s){
     61             edges[p[x]].flow+=a;
     62             edges[p[x]^1].flow-=a;
     63             x=edges[p[x]].from;
     64         }
     65         return a;
     66     }
     67 
     68     int Maxflow(int s,int t){
     69         this->s=s;this->t=t;
     70         BFS();
     71         memset(num,0,sizeof(num));
     72         for(int i=0;i<n;i++)num[d[i]]++;
     73         int x=s;
     74         memset(cur,0,sizeof(cur));
     75         while(d[s]<n){
     76             if(x==t){
     77                 flow+=Augmemt();
     78                 x=s;
     79             }
     80             int ok=0;
     81             for(int i=cur[x];i<G[x].size();i++){
     82                 Edge &e=edges[G[x][i]];
     83                 if(e.cap>e.flow&&d[x]==d[e.to]+1){
     84                     ok=1;
     85                     p[e.to]=G[x][i];
     86                     cur[x]=i;
     87                     x=e.to;
     88                     break;
     89                 }
     90             }
     91             if(!ok){
     92                 int m=n-1;
     93                 for(int i=0;i<G[x].size();i++){
     94                     Edge &e=edges[G[x][i]];
     95                     if(e.cap>e.flow)m=min(m,d[e.to]);
     96                 }
     97                 if(--num[d[x]]==0)break;
     98                 num[d[x]=m+1]++;
     99                 cur[x]=0;
    100                 if(x!=s)x=edges[p[x]].from;
    101             }
    102         }
    103         return flow;
    104     }
    105 }isap;
    106 int n,m,k,day=0,moon=1000;
    107 int fa[1005];
    108 int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
    109 struct SpaceShip{
    110     int h,c;
    111     vector<int> stop;
    112 }ss[25];
    113 inline int read(){
    114     int t;
    115     scanf("%d",&t);
    116     if(t==-1)return moon;
    117     return t;
    118 }
    119 int main(){
    120 //    freopen("e:\in.txt","r",stdin);
    121     scanf("%d%d%d",&n,&m,&k);
    122     isap.init(moon+1);
    123     for(int i=0;i<=moon;i++)fa[i]=i;
    124     for(int i=0;i<m;i++){
    125         int stop;
    126         scanf("%d%d",&ss[i].h,&ss[i].c);
    127         for(int j=0;j<ss[i].c;j++){
    128             stop=read();
    129             ss[i].stop.push_back(stop);
    130             if(j){
    131                 int x=Find(stop),y=Find(ss[i].stop[0]);
    132                 if(x!=y)fa[x]=y;
    133             }
    134         }
    135     }
    136     if(Find(0)!=Find(moon))cout<<0<<endl;
    137     else{
    138         while(isap.flow<k){
    139             for(int i=1;i<=n;i++)isap.AddEdge(i+day*n,i+(day+1)*n,INF);
    140             for(int i=0;i<m;i++){
    141                 int u=ss[i].stop[day%ss[i].c]+day*n,v=ss[i].stop[(day+1)%ss[i].c]+(day+1)*n;
    142                 if(ss[i].stop[day%ss[i].c]==0)u=0;
    143                 if(ss[i].stop[(day+1)%ss[i].c]==moon)v=moon;
    144                 if(ss[i].stop[(day+1)%ss[i].c]==0||ss[i].stop[day%ss[i].c]==moon)continue;
    145                 isap.AddEdge(u,v,ss[i].h);
    146             }
    147             isap.Maxflow(0,moon);
    148             day++;
    149         }
    150         cout<<day<<endl;
    151     }
    152     return 0;
    153 }
  • 相关阅读:
    二叉树的遍历详解:前、中、后、层次遍历(Python实现)
    结对编程——需求建模
    使用 python 与 sqlite3 实现简易的学生信息管理系统
    PowerShell下, MySQL备份与还原遇到的坑
    自动生成四则运算(python实现) 更新
    自动生成四则运算题目(python实现)
    软件工程导论的感想
    矩阵的秩与行列式的几何意义
    微信好友分布分析
    第一次结队作业
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7448332.html
Copyright © 2011-2022 走看看