cjb-poi2011programmingcontest2
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define rep(i,n) for(int i=1;i<=n;i++)
#define mp make_pair
#define pb push_back
using namespace std;
#define PI 3.1415926535897932384626433
#define N 1010
#define M 1000010
#define LF double
#define inf 2147483647
#define stack stck
struct EDGE { int adj, w, next; } edge[M];
int n,m,r,t,k, top, gh[N], nrl[N], S, T;
void addedge(int x, int y, int w) {
edge[++top].adj = y;
edge[top].w = w;
edge[top].next = gh[x];
gh[x] = top;
edge[++top].adj = x;
edge[top].w = 0;
edge[top].next = gh[y];
gh[y] = top;
}
int dist[N], q[N];
int bfs() {
memset(dist, 0, sizeof(dist));
q[1] = S; int head = 0, tail = 1; dist[S] = 1;
while (head != tail) {
int x = q[++head];
for (int p=gh[x]; p; p=edge[p].next)
if (edge[p].w && !dist[edge[p].adj]) {
dist[edge[p].adj] = dist[x] + 1;
q[++tail] = edge[p].adj;
}
}
return dist[T];
}
int dinic(int x, int delta) {
if (x==T) return delta;
for (int& p=nrl[x]; p && delta; p=edge[p].next)
if (edge[p].w && dist[x]+1 == dist[edge[p].adj]) {
int dd = dinic(edge[p].adj, min(delta, edge[p].w));
if (!dd) continue;
edge[p].w -= dd;
edge[p^1].w += dd;
return dd;
}
return 0;
}
int work() {
int ans = 0;
while (bfs()) {
memcpy(nrl, gh, sizeof(gh));
int t; while (t = dinic(S, inf)) ans += t;
}
return ans;
}
pair<int,int> save[M];
vector<int> fuck[N];
int main()
{
cin>>n>>m>>r>>t>>k; top=1;
S=0; T=n+m+1;
rep(i,n)addedge(S,i,1);
rep(i,m)addedge(n+i,T,1);
rep(i,k)
{
scanf("%d%d",&save[i].first,&save[i].second);
addedge(save[i].first,n+save[i].second,1);
}
int ans=0;
long long anst=0;
rep(i,t/r)
{
rep(i,n)edge[2*i].w=1,edge[2*i+1].w=0;
int flow=work(); ans+=flow; anst+=1ll*flow*i*r;
if (!flow)break;
}
cout<<ans<<" "<<anst<<endl;
rep(i,k)if (edge[2*n+2*m+2*i].w==0)fuck[save[i].first].pb(save[i].second);
rep(i,n)
{
int wait=0;
for(auto p:fuck[i]){ printf("%d %d %d\n",i,p,wait); wait+=r; }
}
}
}}}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define rep(i,n) for(int i=1;i<=n;i++)
#define mp make_pair
#define pb push_back
using namespace std;
#define PI 3.1415926535897932384626433
#define N 1010
#define M 1000010
#define LF double
#define inf 2147483647
#define stack stck
struct EDGE { int adj, w, next; } edge[M];
int n,m,r,t,k, top, gh[N], nrl[N], S, T;
void addedge(int x, int y, int w) {
edge[++top].adj = y;
edge[top].w = w;
edge[top].next = gh[x];
gh[x] = top;
edge[++top].adj = x;
edge[top].w = 0;
edge[top].next = gh[y];
gh[y] = top;
}
int dist[N], q[N];
int bfs() {
memset(dist, 0, sizeof(dist));
q[1] = S; int head = 0, tail = 1; dist[S] = 1;
while (head != tail) {
int x = q[++head];
for (int p=gh[x]; p; p=edge[p].next)
if (edge[p].w && !dist[edge[p].adj]) {
dist[edge[p].adj] = dist[x] + 1;
q[++tail] = edge[p].adj;
}
}
return dist[T];
}
int dinic(int x, int delta) {
if (x==T) return delta;
for (int& p=nrl[x]; p && delta; p=edge[p].next)
if (edge[p].w && dist[x]+1 == dist[edge[p].adj]) {
int dd = dinic(edge[p].adj, min(delta, edge[p].w));
if (!dd) continue;
edge[p].w -= dd;
edge[p^1].w += dd;
return dd;
}
return 0;
}
int work() {
int ans = 0;
while (bfs()) {
memcpy(nrl, gh, sizeof(gh));
int t; while (t = dinic(S, inf)) ans += t;
}
return ans;
}
pair<int,int> save[M];
vector<int> fuck[N];
int main()
{
cin>>n>>m>>r>>t>>k; top=1;
S=0; T=n+m+1;
rep(i,n)addedge(S,i,1);
rep(i,m)addedge(n+i,T,1);
rep(i,k)
{
scanf("%d%d",&save[i].first,&save[i].second);
addedge(save[i].first,n+save[i].second,1);
}
int ans=0;
long long anst=0;
rep(i,t/r)
{
rep(i,n)edge[2*i].w=1,edge[2*i+1].w=0;
int flow=work(); ans+=flow; anst+=1ll*flow*i*r;
if (!flow)break;
}
cout<<ans<<" "<<anst<<endl;
rep(i,k)if (edge[2*n+2*m+2*i].w==0)fuck[save[i].first].pb(save[i].second);
rep(i,n)
{
int wait=0;
for(auto p:fuck[i]){ printf("%d %d %d\n",i,p,wait); wait+=r; }
}
}