zoukankan      html  css  js  c++  java
  • UVa11167 Monkeys in the Emei Mountain(最大流)

    题目大概说有n只猴子,猴子们在某个时间段需要喝vi时间的水,各个单位时间段最多允许m只猴子同时喝水,问猴子们能否成功喝水并输出一个可行的方案,输出方案的时间段区间要从小到大排序并且合并连续的区间。

    首先应该能联想到这是最大流的模型。猴子有100只,不过区间的点达到50W,这时考虑离散化,离散化后最多就200个点也就是199个区间。

    • 于是猴子与区间可以作为容量网络的点,新建源点和汇点。
    • 源点向猴子连容量vi的边,区间向汇点连容量为区间包含单位时间段数*m的边。
    • 各个猴子喝水时间段包含的区间,由猴子向区间连容量为区间包含单位时间段数的边。

    这个建图很容易想到。不过这题不是这么容易就解决了。。还要输出方案。

    在残量网络中能知道各个猴子使用的哪几个区间中的多少个时间段。可以通过这个信息去构造出一个可行的方案:从头到尾再回到头循环地把区间内各个时间段安排给各个猴子。

    最后得到区间还要排序下。。然后合并连续区间。。我WA了好久,搞了好久。。合并区间写错了。。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<algorithm>
      5 using namespace std;
      6 #define INF (1<<30)
      7 #define MAXN 333
      8 #define MAXM 333*666
      9 
     10 struct Edge{
     11     int v,cap,next;
     12 }edge[MAXM];
     13 int vs,vt,NE,NV;
     14 int head[MAXN];
     15 
     16 void addEdge(int u,int v,int cap){
     17     edge[NE].v=v; edge[NE].cap=cap;
     18     edge[NE].next=head[u]; head[u]=NE++;
     19     edge[NE].v=u; edge[NE].cap=0;
     20     edge[NE].next=head[v]; head[v]=NE++;
     21 }
     22 
     23 int level[MAXN];
     24 int gap[MAXN];
     25 void bfs(){
     26     memset(level,-1,sizeof(level));
     27     memset(gap,0,sizeof(gap));
     28     level[vt]=0;
     29     gap[level[vt]]++;
     30     queue<int> que;
     31     que.push(vt);
     32     while(!que.empty()){
     33         int u=que.front(); que.pop();
     34         for(int i=head[u]; i!=-1; i=edge[i].next){
     35             int v=edge[i].v;
     36             if(level[v]!=-1) continue;
     37             level[v]=level[u]+1;
     38             gap[level[v]]++;
     39             que.push(v);
     40         }
     41     }
     42 }
     43 
     44 int pre[MAXN];
     45 int cur[MAXN];
     46 int ISAP(){
     47     bfs();
     48     memset(pre,-1,sizeof(pre));
     49     memcpy(cur,head,sizeof(head));
     50     int u=pre[vs]=vs,flow=0,aug=INF;
     51     gap[0]=NV;
     52     while(level[vs]<NV){
     53         bool flag=false;
     54         for(int &i=cur[u]; i!=-1; i=edge[i].next){
     55             int v=edge[i].v;
     56             if(edge[i].cap && level[u]==level[v]+1){
     57                 flag=true;
     58                 pre[v]=u;
     59                 u=v;
     60                 //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
     61                 aug=min(aug,edge[i].cap);
     62                 if(v==vt){
     63                     flow+=aug;
     64                     for(u=pre[v]; v!=vs; v=u,u=pre[u]){
     65                         edge[cur[u]].cap-=aug;
     66                         edge[cur[u]^1].cap+=aug;
     67                     }
     68                     //aug=-1;
     69                     aug=INF;
     70                 }
     71                 break;
     72             }
     73         }
     74         if(flag) continue;
     75         int minlevel=NV;
     76         for(int i=head[u]; i!=-1; i=edge[i].next){
     77             int v=edge[i].v;
     78             if(edge[i].cap && level[v]<minlevel){
     79                 minlevel=level[v];
     80                 cur[u]=i;
     81             }
     82         }
     83         if(--gap[level[u]]==0) break;
     84         level[u]=minlevel+1;
     85         gap[level[u]]++;
     86         u=pre[u];
     87     }
     88     return flow;
     89 }
     90 
     91 int need[111],x[111],y[111];
     92 int point[222],pn;
     93 
     94 struct Interval{
     95     int x,y;
     96     bool operator<(const Interval &i)const{
     97         return x<i.x;
     98     }
     99 }interval[500000];
    100 
    101 int main(){
    102     int cse=0,n,m;
    103     while(~scanf("%d",&n) && n){
    104         scanf("%d",&m);
    105         pn=0; int tot=0;
    106         for(int i=1; i<=n; ++i){
    107             scanf("%d%d%d",need+i,x+i,y+i);
    108             tot+=need[i];
    109             point[pn++]=x[i];
    110             point[pn++]=y[i];
    111         }
    112         sort(point,point+pn);
    113         pn=unique(point,point+pn)-point;
    114 
    115         vs=0; vt=n+pn+1; NV=vt+1; NE=0;
    116         memset(head,-1,sizeof(head));
    117 
    118         for(int i=1; i<pn; ++i){
    119             addEdge(i+n,vt,m*(point[i]-point[i-1]));
    120         }
    121         for(int i=1; i<=n; ++i){
    122             addEdge(vs,i,need[i]);
    123             int from=lower_bound(point,point+pn,x[i])-point;
    124             int to=lower_bound(point,point+pn,y[i])-point;
    125             for(int j=from+1; j<=to; ++j){
    126                 addEdge(i,j+n,point[j]-point[j-1]);
    127             }
    128         }
    129 
    130         if(ISAP()!=tot){
    131             printf("Case %d: No
    ",++cse);
    132             continue;
    133         }
    134         printf("Case %d: Yes
    ",++cse);
    135 
    136         int cnt[222]={0};
    137 
    138         for(int u=1; u<=n; ++u){
    139             int in=0;
    140             for(int i=head[u]; i!=-1; i=edge[i].next){
    141                 if(i&1 || edge[i^1].cap==0) continue;
    142                 int k=edge[i].v-n,tot=point[k]-point[k-1];
    143                 if(cnt[k]+edge[i^1].cap<=tot){
    144                     interval[in].x=point[k-1]+cnt[k];
    145                     interval[in].y=point[k-1]+cnt[k]+edge[i^1].cap;
    146                     ++in;
    147                     cnt[k]+=edge[i^1].cap;
    148                 }else if(cnt[k]==tot){
    149                     interval[in].x=point[k-1];
    150                     interval[in].y=point[k-1]+edge[i^1].cap;
    151                     ++in;
    152                     cnt[k]=edge[i^1].cap;
    153                 }else{
    154                     interval[in].x=point[k-1]+cnt[k];
    155                     interval[in].y=point[k];
    156                     ++in;
    157                     cnt[k]+=edge[i^1].cap; cnt[k]-=tot;
    158                     interval[in].x=point[k-1];
    159                     interval[in].y=point[k-1]+cnt[k];
    160                     ++in;
    161                 }
    162             }
    163             sort(interval,interval+in);
    164             int tot=in;
    165             for(int i=1; i<in; ++i){
    166                 if(interval[i].x==interval[i-1].y){
    167                     --tot;
    168                 }
    169             }
    170             printf("%d",tot);
    171             for(int i=0; i<in; ){
    172                 int j=i+1;
    173                 while(j<in && interval[j-1].y==interval[j].x){
    174                     ++j;
    175                 }
    176                 printf(" (%d,%d)",interval[i].x,interval[j-1].y);
    177                 i=j;
    178             }
    179             putchar('
    ');
    180         }
    181     }
    182     return 0;
    183 }
  • 相关阅读:
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之六 多点触控
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之九 定位
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之七 重力感应
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之五 保存数据的几种方式
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之八 照相机
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之三 Application 配置详解
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之四 打开与关闭应用程序是的保存数据
    ADOBE FLASH BUILDER 4.6 IOS 开发之部署与调试
    [译] 高性能JavaScript 1至5章总结
    页签及盒子的web标准实现
  • 原文地址:https://www.cnblogs.com/WABoss/p/5724862.html
Copyright © 2011-2022 走看看