其他分享
首页 > 其他分享> > hdu3072Intelligence System(缩图+贪心)

hdu3072Intelligence System(缩图+贪心)

作者:互联网

传送门

题意:给我们一个有向图,形成环的路线不需要收费,形成环的路线上的所有点不收费,

对于其余点,我们需找到一个生成树,花费最小

吐槽:这题把我人搞晕了,先是看题没看懂,没看到形成环的路线上的点不收费这条,然后就

使劲想也不可能做出来,看了题解还没一个正常的,全是抄一个人的,那个人还没注释,模板还跟我很不一样,

然后还写的很丑,变量定义那些巨怪,就能不创新数组就不创,我不知道你在节约个啥,多搞点数组会死啊,

终于看懂他的模板然后才知道环上的点不收费,然后套上自己的模板又超时了...思来想去以为是dfs死循环了

又写了个tuopo版本的贪心,结果还是超时,最后的最后发现是hd数组没初始化,我.....

思路:就是把先缩点,把那些不需要付钱的点去掉,然后再贪心

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 50100;
typedef long long ll;
struct edge {
	int f, t, w,nxt;
}e[maxn << 1];
int hd[maxn], tot;
void add(int f, int t,int w) {
	e[++tot] = { f,t,w,hd[f]};
	hd[f] = tot;
}
int n, m;
int low[maxn], dfn[maxn], cnt;
int stk[maxn], sk, instk[maxn];
int col[maxn], colnum;
int du[maxn],cost[maxn], vis[maxn];
void init() {
	memset(hd, 0, sizeof(hd));
	memset(dfn, 0, sizeof(dfn));
	memset(vis, 0, sizeof(vis));
	memset(du, 0, sizeof(du));
	memset(col, 0, sizeof(col));
	cnt = sk = colnum = tot = 0;
}
void tarjan(int u) {//缩点
	low[u] = dfn[u] = ++cnt;
	stk[++sk] = u; instk[u] = 1;
	for (int i = hd[u]; i; i = e[i].nxt) {
		int v = e[i].t;
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if(instk[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		colnum++;
		while (1) {
			int v = stk[sk--];
			instk[v] = 0;
			col[v] = colnum;
			if (v == u)break;
		}
	}
}
//void dfs(int u) {
//	if (vis[u])return;
//	vis[u] = 1;
//	for (int i = hd[u]; i; i = e[i].nxt) {
//		int v = e[i].t, w = e[i].w;
//		dfs(v);
//		if (w < cost[v])cost[v] = w;
//	}
//}
int tuopo() {//贪心
	queue<int>q;
	memset(cost, 0x3f, sizeof(cost));//初始化设置为一个很大的数
	for (int i = 1; i <= colnum; i++) {
		if (!du[i]) {
			cost[i] = 0;
			q.push(i);
		}
	}
	while (!q.empty()) {
		int u = q.front(); q.pop();
		for (int i = hd[u]; i; i = e[i].nxt) {
			int v = e[i].t, w = e[i].w;
			if (cost[v] > w)cost[v] = w;
			du[v]--;
			if (du[v] == 0) q.push(v);
		}
	}
	int ans = 0;
	for (int i = 1; i <= colnum; i++) {
		ans += cost[i];
	}
	return ans;
}
int main() {
	//freopen("test.txt", "r", stdin);
	while (~scanf("%d%d", &n, &m)) {
		init();
		for (int i = 1; i <= m;i++) {
			int a, b, w; scanf("%d%d%d", &a, &b, &w);
			add(a, b, w);
		}
		for (int i = 0; i < n; i++) {
			if (!dfn[i]) {
				tarjan(i);
			}
		}
		memset(hd, 0, sizeof(hd)); tot = 0;
		for (int i = 1; i <= m; i++) {//重新建图
			int u = e[i].f, v = e[i].t, w = e[i].w;
			if (col[u] != col[v]) {
				add(col[u], col[v], w);
				du[col[v]]++;
			}
		}
		/*
		memset(cost,0x3f,sizeof(cost));
		for (int i = 1; i <= colnum; i++) {
			if (du[i] == 0) {
				cost[i] = 0;
				dfs(i);
			}
		}*/
		/*int ans = 0;
		for (int i = 1; i <= colnum; i++) {
			ans += cost[i];
		}*/
		printf("%d\n",tuopo());
	}
	return 0;
}

  

标签:缩图,int,System,cost,hdu3072Intelligence,数组,收费,模板,贪心
来源: https://www.cnblogs.com/MYMYACMer/p/14612309.html