http://codevs.cn/problem/1034/
题解:
按照时间建立分层图,建立超级源和超级汇,最大流量等于总人数时就退出。
代码:
错哪了呢?
状态: 运行错误(内存访问非法) Runtime Error
得分 : 60
总时间耗费: 48ms
总内存耗费: 10 kB
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxm = 20 + 10;
const int maxn = 20000 + 10;
const int INF = 1000000007;
struct Edge {
int from, to, cap, flow;
};
vector<Edge> edges;
vector<int> G[maxn];
void AddEdge(int from, int to, int cap) {
edges.push_back((Edge){from, to, cap, 0});
edges.push_back((Edge){to, from, 0, 0});
int m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
int n, m, k;
int s = 0, t = 1;
int c = 0;
#define earth 3
#define moon 2
int d[maxn], cur[maxn];
bool vis[maxn];
bool BFS() {
memset(vis, 0, sizeof(vis));
memset(d, 0, sizeof(d));
vis[s] = 1; d[s] = 0;
queue<int> Q;
Q.push(s);
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(e.cap > e.flow && !vis[e.to]) {
Q.push(e.to);
vis[e.to] = 1;
d[e.to] = d[x] + 1;
}
}
}
return vis[t];
}
int DFS(int x, int a) {
if(x == t || a == 0) return a;
int f, flow = 0;
for(int &i = cur[x]; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(e.cap > e.flow && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) {
flow += f;
a -= f;
edges[G[x][i]].flow += f;
edges[G[x][i]^1].flow -= f;
}
}
return flow;
}
int Maxflow(int& flow) {
while(BFS()) {
memset(cur, 0, sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}
int hp[maxm], p[maxm];
vector<int> cycle[maxm];
int encode(int x) {
return n*c + x;
}
void refresh_graph() {
for(int x = 1; x <= m; x++) {
int r = cycle[x].size();
int y = encode(cycle[x][c%r]);
if(p[x]) {
AddEdge(p[x], y, hp[x]);
AddEdge(p[x], encode(cycle[x][(c-1)%r]), k);
}
p[x] = y;
}
for(int i = encode(moon); i <= encode(n); i++) AddEdge(i-n, i, k);
AddEdge(encode(moon), t, INF);
for(int i = 0; i < edges.size(); i++) {
Edge& e = edges[i];
if(!e.cap) e.flow = 0;
}
}
//0: super source
//1: super terminal
//2: the moon at 1'c
//3: the earth at 1'c
bool g[maxm][maxm];
bool is_scc() {
g[s][earth] = g[moon][t] = 1;
for(int x = 1; x <= m; x++)
for(int i = 0; i < cycle[x].size()-1; i++) {
int from = cycle[x][i];
int to = cycle[x][i+1];
g[from][to] = g[to][from] = 1;
}
queue<int> Q;
Q.push(s);
vis[s] = 1;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = 0; i <= n+1; i++) if(g[x][i] && !vis[i]) {
vis[i] = 1;
Q.push(i);
}
}
return vis[t];
}
int main() {
cin >> n >> m >> k;
for(int x = 1; x <= m; x++) {
int cnt; cin >> hp[x] >> cnt;
for(int i = 1; i <= cnt; i++) {
int y; cin >> y;
cycle[x].push_back(y+3);
}
p[x] = cycle[x][0];
}
n += 2;
AddEdge(s, encode(earth), k);
AddEdge(encode(moon), t, k);
if(is_scc()) {
int flow = 0;
while(1) {
c++;
refresh_graph();
if(Maxflow(flow) >= k) {
cout << c << endl;
break;
}
}
} else {
cout << 0 << endl;
}
return 0;
}