Annual Congress of MUD(最大流)

Annual Congress of MUD

时间限制: 1 Sec  内存限制: 128 MB
提交: 80  解决: 10
[提交] [状态] [讨论版] [命题人:admin]

题目描述

Multiuser dungeon games, also called MUD games, are real-time virtual-world multiplayer games that are usually played online with text-based commands. The players do not meet normally, but every year, there is the Annual Congress of MUD (ACM) where MUD lovers all around the world could meet in person.
ACM is so popular that the event each year spans around 20 days. Each day, there will be a special gathering for MUD game designers to introduce their new games to the others. 
Each player will usually spend a few days on the ACM site, and in-between will be invited in exactly one day to join this special gathering.
This year, ACM is held at your city, and your boss is an organiser, and he wants to find a best way to assign the players to these special gatherings (one player to one special gathering within his or her duration of stay), so that the maximum number of players among all gatherings is minimized.
Your boss is an extremely impatient guy. He wants to have a system that can tell the maximum number of players among all gatherings, in any best assignment, after each player enters his or her duration of stay. Your task is to help your boss develop such a system.

 

输入

An instance of the problem consists of N + 1 lines. The first line specifies the integers N and D, seperated by a space. In the ith line of the following N lines, it contains two integers xi and yi , separated by a space. Note that the test data file may contain more than one instance. The last instance is followed by a line containing a single 0.

 

输出

For each instance, an integer i is marked if and only if the maximum number of players in the best assignment increases after the duration of stay [xi , yi ] of the ith player is keyed in. By default, 1 is always marked. The output of the corresponding instance is the list of all marked integers in ascending order, separated by a space between successive integers, followed by a newline character.

 

样例输入

3 3
1 1
1 1
1 1
3 3
1 2
2 3
1 1
3 3
1 2
1 2
1 2
0

 

样例输出

1 2 3
1
1 3
思路:将每个区间看作一个点,在源点s与输入的区间之间连一条流量为一的边,如果该区间已经存在,则将对应边的流量加一;
在每一个区间与区间内每一个点之间建一条流量为无穷的边;
在所有1~D的点与汇点t之间建一条流量为max的边,max为当前的the maximum number of players among all gatherings;
当然max起始为0.
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int MAXN=305;
  4 const int INF=1e9+7;
  5 struct Max_flow
  6 {
  7     struct
  8     {
  9         int v,cap,next;
 10     } e[MAXN*MAXN];
 11     int cnt_edge,cur_clk,head[MAXN];
 12     void init(int cnt)
 13     {
 14         cnt_edge=0;
 15         memset(head,0xff,sizeof(int)*cnt);
 16     }
 17     int add_edge_(int u,int v,int cap)
 18     {
 19         e[cnt_edge]={v,cap,head[u]};
 20         head[u]=cnt_edge;
 21         return cnt_edge++;
 22     }
 23     int add_edge(int u,int v,int cap)
 24     {
 25         int res=add_edge_(u,v,cap);
 26         add_edge_(v,u,0);
 27         return res;
 28     }
 29     int clk[MAXN],pre[MAXN];
 30     queue<int> que;
 31     bool bfs(int s,int t)
 32     {
 33         while(!que.empty()) que.pop();
 34         cur_clk++;
 35         clk[s]=cur_clk;
 36         que.push(s);
 37         while(!que.empty())
 38         {
 39             int u=que.front();
 40             que.pop();
 41             for(int i=head[u]; i!=-1; i=e[i].next)
 42             {
 43                 if(e[i].cap>0)
 44                 {
 45                     int v=e[i].v;
 46                     if(clk[v]!=cur_clk)
 47                     {
 48                         pre[v]=i;
 49                         clk[v]=cur_clk;
 50                         if(v==t) return true;
 51                         que.push(v);
 52                     }
 53                 }
 54             }
 55         }
 56         return false;
 57     }
 58     int max_flow(int s,int t)
 59     {
 60         int flow=0;
 61         while(bfs(s,t))
 62         {
 63             int min_cap=INF;
 64             for(int u=t;u!=s;u=e[pre[u]^1].v)
 65             {
 66                 if(min_cap>e[pre[u]].cap) min_cap=e[pre[u]].cap;
 67             }
 68             for(int u=t; u!=s; u=e[pre[u]^1].v)
 69             {
 70                 e[pre[u]].cap-=min_cap;
 71                 e[pre[u]^1].cap+=min_cap;
 72             }
 73             flow+=min_cap;
 74         }
 75         return flow;
 76     }
 77 } G;
 78 int vis[30][30],idx[30][30],edg_t[30],s_edg[MAXN];
 79 int n,d,now,m,s,t,flow;
 80 bool flag;
 81 int main()
 82 {
 83     while(scanf("%d",&n)!=EOF && n)
 84     {
 85         now++,m=0,flow=0,flag=false;
 86         scanf("%d",&d);
 87         for(int i=0;i<d;i++)
 88         {
 89             for(int j=i;j<d;j++)
 90             {
 91                 idx[i][j]=m++;
 92             }
 93         }
 94         G.init(m+d+2);
 95         s=m+d,t=m+d+1;
 96         for(int i=0;i<d;i++) edg_t[i]=G.add_edge(m+i,t,0);
 97         for(int i=0;i<n;i++)
 98         {
 99             int x,y;
100             scanf("%d %d",&x,&y);
101             x--,y--;
102             int v=idx[x][y];
103             if(vis[x][y]!=now)
104             {
105                 vis[x][y]=now;
106                 for(int i=x;i<=y;i++) G.add_edge(v,m+i,INF);
107                 s_edg[v]=G.add_edge(s,v,1);
108             }
109             else
110             {
111                 G.e[s_edg[v]].cap++;
112             }
113             flow+=G.max_flow(s,t);
114             //cout<<"ni"<<"->"<<flow<<endl;
115             if(flow!=i+1)
116             {
117                 if(flag) printf(" ");
118                 else flag=true;
119                 printf("%d",i+1);
120                 for(int i=0;i<d;i++) G.e[edg_t[i]].cap++;
121             }
122         }
123         puts("");
124     }
125     return 0;
126 }
View Code

 

posted @ 2018-09-04 23:22  Gang_Li  阅读(176)  评论(0编辑  收藏  举报