3624: [Apio2008]免费道路

3624: [Apio2008]免费道路

Time Limit: 2 Sec   Memory Limit: 128 MBSec   Special Judge
Submit: 921   Solved: 371
[ Submit][ Status][ Discuss]

Description

Input

Output

Sample Input

5 7 2
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1

Sample Output

3 2 0
4 3 0
5 3 1
1 2 1

HINT

Source

[ Submit][ Status][ Discuss]



先把所有边排序,优先选择水泥路,这样做最小生成树

这样得到的这棵树,这其中的鹅卵石路显然是一定得存在于答案中

如果这个数目太大,当然no solution

重新建树,先把一定需要的鹅卵石路算上

然后优先选择鹅卵石路,搞到刚好k条,如果可以,那就有解


这样做显然是对的,因为只要能新增鹅卵石路,那么就相当于在原树中删掉一条水泥路

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 1E5 + 10;

struct E{
	int x,y,typ;
	E(){}
	E(int x,int y,int typ): x(x),y(y),typ(typ){}
	bool operator < (const E &b) const {
		return typ > b.typ;
	} 
}edgs[maxn];

int n,m,k,fa[maxn];
bool Mark[maxn],Ans[maxn];

int getfa(int x) {return x == fa[x]?x:fa[x] = getfa(fa[x]);}
int getint()
{
	char ch = getchar();
	int ret = 0;
	while (ch < '0' || '9' < ch) ch = getchar();
	while ('0' <= ch && ch <= '9')
		ret = ret*10 + ch - '0',ch = getchar();
	return ret;
}

int main()
{
	#ifdef DMC
		freopen("DMC.txt","r",stdin);
	#endif
	
	n = getint();
	m = getint();
	k = getint();
	for (int i = 1; i <= m; i++) {
		int x = getint();
		int y = getint();
		int typ = getint();
		edgs[i] = E(x,y,typ);
	} 
		
	sort(edgs + 1,edgs + m + 1);
	for (int i = 1; i <= n; i++) fa[i] = i;
	int tot = 0;
	for (int i = 1; i <= m; i++) {
		int fx = getfa(edgs[i].x);
		int fy = getfa(edgs[i].y);
		if (fx != fy) {
			fa[fx] = fy;
			if (!edgs[i].typ) ++tot;
			Mark[i] = 1;
		}
	}
	
	if (tot > k) {
		puts("no solution");
		return 0;
	}
	
	if (tot == k) {
		for (int i = 1; i <= m; i++)
			if (Mark[i])
				printf("%d %d %d\n",edgs[i].x,edgs[i].y,edgs[i].typ);
		return 0;
	}
	
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++)
		if (Mark[i] && !edgs[i].typ) {
			int fx = getfa(edgs[i].x);
			int fy = getfa(edgs[i].y);
			fa[fx] = fy;
			Ans[i] = 1;
		}
	for (int i = 1; i <= m; i++)
		if (!edgs[i].typ && !Mark[i]) {
			int fx = getfa(edgs[i].x);
			int fy = getfa(edgs[i].y);
			if (fx != fy) {
				fa[fx] = fy;
				++tot;
				Ans[i] = 1;
			}
			if (tot == k) break;
		}
	if (tot < k) {
		puts("no solution");
		return 0;
	}
	for (int i = 1; i <= m; i++) {
		int fx = getfa(edgs[i].x);
		int fy = getfa(edgs[i].y);
		if (fx != fy) {
			fa[fx] = fy;
			Ans[i] = 1;
		}
	}
	for (int i = 1; i <= m; i++)
		if (Ans[i])
			printf("%d %d %d\n",edgs[i].x,edgs[i].y,edgs[i].typ);
	return 0;
}

你可能感兴趣的:(模拟)