Destroy Walls

Problem Description
Long times ago, there are beautiful historic walls in the city. These walls divide the city into many parts of area.

Since it was not convenient, the new king wants to destroy some of these walls, so he can arrive anywhere from his castle. We assume that his castle locates at (0.62,0.63).

There are n towers in the city, which numbered from 1 to n. The ith's location is (xi,yi). Also, there are m walls connecting the towers. Specifically, the ith wall connects the tower ui and the tower vi(including the endpoint). The cost of destroying the ith wall is wi.

Now the king asks you to help him to divide the city. Firstly, the king wants to destroy as less walls as possible, and in addition, he wants to make the cost least.

The walls only intersect at the endpoint. It is guaranteed that no walls connects the same tower and no 2 walls connects the same pair of towers. Thait is to say, the given graph formed by the walls and towers doesn't contain any multiple edges or self-loops.

Initially, you should tell the king how many walls he should destroy at least to achieve his goal, and the minimal cost under this condition.
 

Input
There are several test cases.

For each test case:

The first line contains 2 integer n, m.

Then next n lines describe the coordinates of the points.

Each line contains 2 integers xi,yi.

Then m lines follow, the ith line contains 3 integers ui,vi,wi

|xi|,|yi|105

3n100000,1m200000

1ui,vin,uivi,0wi10000
 

Output
For each test case outout one line with 2 integers sperate by a space, indicate how many walls the king should destroy at least to achieve his goal, and the minimal cost under this condition.
 

Sample Input
 
  
4 4-1 -1-1 11 11 -11 2 12 3 23 4 14 1 2
 
Sample Output
 
  
1 1

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
/*
 看到这道题,我想到了欧拉公式,知道应该是最小生成树,节点就是 区域,然后就卡死在了 怎样来进行区域划分
 反,反,反 过来想,我们想要最小生成树,然后它是和相邻区域的边是 一一对应的,
 想想剩下的边,应该是一种什么情况,那就是最大生成树,或者不一定成为树,只是森林
 不过这个坐标是真的气,写的这么好,什么用没有 
 !!!还有就是欧拉公式 F=E+2-V,这样的适用于 连通图, 
*/

const int maxm=2e5+10;
const int maxn=1e5+10;

struct Edge{
	int w;
	int u,v;
	Edge(){}
	Edge(int _u,int _v,int _w):u(_u),v(_v),w(_w){	}
	bool operator<(const Edge& obj)const{
		return w>obj.w;
	}
}edge[maxm];

int pre[maxn];
int find(int x){
	return pre[x]==x?x:pre[x]=find(pre[x]);
}

void join(int& num,int u,int v,int w,int& ans){
	int ru=find(u),rv=find(v);
	if(ru!=rv){
		pre[ru]=rv;
		ans-=w;
		num++;
	}
}

int main()
{
	int n,m;
	while(scanf("%d %d",&n,&m)==2){
		for(int i=1;i<=n;i++){
			pre[i]=i;
			int x,y;
			scanf("%d %d",&x,&y);
		}	
		int ans=0;
		for(int i=0;i<m;i++){
			int u,v,w;
			scanf("%d %d %d",&u,&v,&w);
			edge[i]=Edge(u,v,w);
			ans+=w;
		}
		sort(edge,edge+m);
		int num=0;
		for(int i=0;i<m;i++){
			int u=edge[i].u,v=edge[i].v;
			join(num,u,v,edge[i].w,ans);
		}
		printf("%d %d\n",m-num,ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36424540/article/details/81046827