UVALive -- 6571 -- It Can Be Arranged [split point + isap] minimum cut, uvalive
Link:Https://icpcarchive.ecs.baylor.edu/index.php? Option = com_onlinejudge & Itemid = 8 & page = show_problem & problem = 4582
Question:There are n courses, each of which has a start time and end time, and the number of participants. Now we want to rent a classroom to attend the course. Let me tell you a matrix. a [I] [j] indicates the j class. If the I class is used in the classroom after the I class, the end time of I + a [I] [j] must be strictly less than the start time of j. Ask the minimum number of classrooms to borrow.
The graph creation model for this question was previously done. It is similar to the idea of poj3469 (problem-solving Report), but it was not made during the competition today. I thought it was greedy .. I also thought about how to build a graph for a while, but I didn't think of it. After reading the code of Bao Ge, I found that I had done this kind of problem before. I am ashamed that this is a question that should be made. In the future, you still have to read your blog regularly and review previous things. Otherwise, you will forget everything.
Ideas:Record the sum of the number of classrooms required for each course to use the classroom separately. Use the network flow to find the maximum number of classrooms that can be shared with num. sum-num is the number of required classrooms.
Graph creation:Think of each course as a vertex p, split p into p 'and p '', and connect the source point to p'. The capacity is the number of rooms required for this course, p ''indicates the same arc capacity of the consortium point. For the cleaning time matrix, if the end time of I + a [I] [j] is strictly less than the start time of j, the I 'and j ''are connected to an arc with the capacity of INF. In this way, for any cut in the graph, the source points and sink points are not connected, so each classroom node will only be connected to one of the source points and sink points, that is, every course has a classroom. Find the maximum flow of the network, which is equivalent to the minimum cut, indicating the maximum number of rooms that can be shared.
#include<cstring>#include<string>#include<fstream>#include<iostream>#include<iomanip>#include<cstdio>#include<cctype>#include<algorithm>#include<queue>#include<map>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstdlib>#include<functional>#include<cmath>using namespace std;#define PI acos(-1.0)#define MAXN 101000#define eps 1e-7#define INF 0x7FFFFFFF#define LLINF 0x7FFFFFFFFFFFFFFF#define seed 1313131#define MOD 1000000007#define ll long long#define ull unsigned ll#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct node{ int u,v,w,next;}edge[500000];int head[220],dist[220],cur[220],fa[220],num[220],vis[220];int n,m,k,cnt,nn,src,sink;void add_edge(int a,int b,int c){ edge[cnt].u = a; edge[cnt].v = b; edge[cnt].w = c; edge[cnt].next = head[a]; head[a] = cnt++;}void bfs(){ int x,i,j; queue<int> q; memset(dist,-1,sizeof(dist)); q.push(sink); dist[sink] = 0; while(!q.empty()){ x = q.front(); q.pop(); for(i=head[x];i!=-1;i=edge[i].next){ if(dist[edge[i].v]<0){ dist[edge[i].v] = dist[x] + 1; q.push(edge[i].v); } } }}int augment(){ int x=sink,a=INF; while(x!=src){ a = min(a,edge[fa[x]].w); x = edge[fa[x]].u; } x=sink; while(x!=src){ edge[fa[x]].w -= a; edge[fa[x]^1].w += a; x = edge[fa[x]].u; } return a;}int isap(){ int i,x,ok,minm,flow=0; memset(num,0,sizeof(num)); bfs(); for(i=0;i<=nn+5;i++) if(dist[i]!=-1) num[dist[i]]++; for(i=0;i<=nn+5;i++) cur[i] = head[i]; x=src; while(dist[src]<nn){ if(x==sink){ flow += augment(); x = src; } ok=0; for(i=cur[x];i!=-1;i=edge[i].next){ if(edge[i].w && dist[x]==dist[edge[i].v]+1){ ok=1; fa[edge[i].v] = i; cur[x] = i; x = edge[i].v; break; } } if(!ok){ minm = nn + 5; for(i=head[x];i!=-1;i=edge[i].next) if(edge[i].w && dist[edge[i].v]<minm) minm=dist[edge[i].v]; if(--num[dist[x]]==0)break; num[dist[x]=minm+1]++; cur[x]=head[x]; if(x!=src) x=edge[fa[x]].u; } } return flow;}struct node1{ int s,t,num;}a[120];int main(){ int i,j,t,cas=1; int b,c; scanf("%d",&t); while(t--){ memset(head,-1,sizeof(head)); cnt = 0; scanf("%d%d",&n,&m); src = 0; sink = 2 * n + 1; nn = sink + 1; int sum = 0; for(i=1;i<=n;i++){ scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].num); int temp; if(a[i].num%m) temp = a[i].num / m + 1; else temp = a[i].num / m; sum += temp; add_edge(src,i,temp); add_edge(i,src,0); add_edge(i+n,sink,temp); add_edge(sink,i+n,0); } for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ scanf("%d",&b); if(a[i].t+b<a[j].s){ add_edge(i,j+n,INF); add_edge(j+n,i,0); } } } printf("Case %d: %d\n",cas++,sum-isap()); } return 0;}