[codevs 1034] 家园

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;
}


posted @ 2015-02-03 15:54  wfwbz  阅读(126)  评论(0编辑  收藏  举报