欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

题解 P3275 【[SCOI2011]糖果】

程序员文章站 2024-03-23 15:46:16
...

清深夏令营机考压轴题,对差分约束的认识还是不够深刻,算法写出来了图没建对,/(ㄒoㄒ)/~~

题解 P3275 【[SCOI2011]糖果】
题解 P3275 【[SCOI2011]糖果】
题解 P3275 【[SCOI2011]糖果】

#define inf 0x3f3f3f3f
#define ll long long
#define vec vector<int>
#define P pair<int,int>
#define MAX 100005

int N, K, x, a, b, vis[MAX], cnt[MAX], dist[MAX];
struct edge {
	int v, c;
	edge(int a = 0, int b = 0) { v = a, c = b; }
};
vector<edge>G[MAX];

void addEdge(int x, int a, int b) {
	if (x == 1)G[a].push_back(edge(b, 0)), G[b].push_back(edge(a, 0));
	else if (x == 2)G[a].push_back(edge(b, 1));
	else if (x == 3)G[b].push_back(edge(a, 0));
	else if (x == 4)G[b].push_back(edge(a, 1));
	else G[a].push_back(edge(b, 0));
}

bool spfa(int s) {
	memset(vis, 0, sizeof(vis));
	memset(cnt, 0, sizeof(cnt));
	fill(dist, dist + MAX, 0);
	queue<int> q; q.push(s); vis[s] = 1; dist[s] = 0;

	while (!q.empty()) {
		int u = q.front(); q.pop(); cnt[u]++; vis[u] = 0;
		if (cnt[u] == N)return false;
		for (int i = 0; i < G[u].size(); i++) {
			edge e = G[u][i];
			if (dist[u] + e.c > dist[e.v]) {
				dist[e.v] = dist[u] + e.c;
				if (!vis[e.v]) {
					vis[e.v] = 1;
					q.push(e.v);
				}
			}
		}
	}
	return true;
}

int main() {
	while (scanf("%d %d", &N, &K) != EOF) {
		for (int i = 0; i <= N; i++) {
			G[i].clear();
			if (i != 0)G[0].push_back(edge(i, 1));//超级源点
		}
		int sign = 1;
		for (int i = 0; i < K; i++) {
			scanf("%d %d %d", &x, &a, &b);
			if (x == 2 || x == 4) {
				if (a == b) { sign = 0; }
			}
			addEdge(x, a, b);
		}
		if (!sign) { cout << -1 << endl; continue; }

		if (!spfa(0))cout << -1 << endl;
		else {
			ll mi = inf, res = 0;
			for (int i = 1; i <= N; i++) {
				if (dist[i] < mi)mi = dist[i];
				res += dist[i];
			}
			if (mi < 0)
				res += (-mi + 1)*N;
			cout << res << endl;
		}
	}
}
相关标签: ACM图论/网络流