1. 程式人生 > >Annual Congress of MUD(最大流)

Annual Congress of MUD(最大流)

sep edge after empty real-time test span called per

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

Annual Congress of MUD(最大流)