您的位置:首页 > 其它

UVALive 2957 Bring Them There

2015-10-30 16:44 411 查看

Bring Them There

Time Limit: 3000ms
Memory Limit: 131072KB
This problem will be judged on UVALive. Original ID: 2957
64-bit integer IO format: %lld Java class name: Main

By the year 3141, the human civilization has spread all over the galaxy. The special hypertunnels are used to travel from one star system to another. To use the hypertunnel, you fly to a special location near the source star using your spaceship, activate the hyperjumper, fly through the hypertunnel, get out near your destination star and fly to the planet you need. The whole process takes exactly one day. A small drawback of the system is that for each tunnel every day only one spaceship can travel using this tunnel.

You are working in the transportation department of the ``Intergalaxy Business Machines" company. This morning your boss has assigned a new task to you. To run the programming contest IBM needs to deliver K supercomputers from Earth where the company headquarters are located to the planet Eisiem. Since supercomputers are very large, one needs the whole spaceship to carry each supercomputer. You are asked to find a plan to deliver the supercomputers that takes as few days as possible. Since IBM is a very powerful corporation, you may assume that any time you need some tunnel for hyperjump, it is at your service. However, you still can use each tunnel only once a day.

Input

Input consists of several datasets. The first line of each dataset contains N - the number of star systems in the galaxy, M - the number of tunnels, K - the number of supercomputers to be delivered, S - the number of the solar system (the system where planet Earth is) and T - the number of the star system where planet Eisiem is (2

#include <bits/stdc++.h>
using namespace std;
const int INF = ~0U>>2;
const int maxn = 5010;
struct arc {
int to,flow,next;
arc(int x = 0,int y = 0,int z = -1) {
to = x;
flow = y;
next = z;
}
} e[maxn*100];
int head[maxn],d[maxn],cur[maxn],tot,S,T;
void add(int u,int v,int flow) {
e[tot] = arc(v,flow,head[u]);
head[u] = tot++;
e[tot] = arc(u,0,head[v]);
head[v] = tot++;
}
bool bfs() {
queue<int>q;
memset(d,-1,sizeof d);
q.push(S);
d[S] = 1;
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].flow && d[e[i].to] == -1) {
d[e[i].to] = d[u] + 1;
q.push(e[i].to);
}
}
}
return d[T] > -1;
}
int dfs(int u,int low) {
if(u == T) return low;
int a,tmp = 0;
for(int &i = cur[u]; ~i; i = e[i].next) {
if(e[i].flow &&d[e[i].to] == d[u]+1&&(a=dfs(e[i].to,min(low,e[i].flow)))) {
e[i].flow -= a;
e[i^1].flow += a;
low -= a;
tmp += a;
break;
}
}
if(!tmp) d[u] = -1;
return tmp;
}
int dinic(int bound,int ret = 0) {
while(ret < bound && bfs()) {
memcpy(cur,head,sizeof head);
ret += dfs(S,INF);
}
return ret;
}
int n,m,k,s,t;
int x[maxn],y[maxn];
void output(int day) {
int to[2000],vis[2000],s[2000],t[2000];
for(int i = 1; i <= k; ++i) to[i] = S;
int id = 0;
for(int d = 1; d <= day; ++d) {
id += (n<<1); //跳过计算机停留在某个星球上一天的边
int cnt = 0;
for(int i = 0; i < m; ++i) {
int flow1 = e[id].flow;
id += 2;
int flow2 = e[id].flow;
id += 2;
if(flow1 && !flow2) s[cnt] = y[i], t[cnt++] = x[i];
if(flow2 && !flow1) s[cnt] = x[i], t[cnt++] = y[i];
}
memset(vis,0,sizeof vis);
printf("%d", cnt);
for(int i = 0; i < cnt; ++i)
for(int j = 1; j <= k; ++j)
if(s[i] == to[j] && !vis[j]) {
printf(" %d %d", j, t[i]);
to[j] = t[i];
vis[j] = 1;
break;
}
printf("\n");
}
}
void solve() {
int ret = 0,day = 0;
while(ret < k) {
++day;
for(int i = 1; i <= n; ++i)
add((day - 1)*n + i,day*n + i,INF);
for(int i = 0; i < m; ++i) {
add(x[i] + (day - 1)*n,y[i] + day*n,1);
add(y[i] + (day - 1)*n,x[i] + day*n,1);
}
S = s;
T = t + day*n;
ret += dinic(k - ret);
}
printf("%d\n",day);
output(day);
}
int main() {
while(~scanf("%d%d%d%d%d",&n,&m,&k,&s,&t)) {
memset(head,-1,sizeof head);
for(int i = tot = 0; i < m; ++i)
scanf("%d%d",x + i,y + i);
solve();
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: