hdu 6187 Destroy Walls

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.6∗√2,0.6∗√3).

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

3≤n≤100000,1≤m≤200000

1≤ui,vi≤n,ui≠vi,0≤wi≤10000

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 1
1 1
1 -1
1 2 1
2 3 2
3 4 1
4 1 2

Sample Output

1 1

【题意】

给你n个点,m条边,构成一张图,显然这个图可能会有环路,现在已知每条边都有一个权值,现在让你删掉一些边,使得图中不存在环。问你最少要删掉几条边,在删掉这么多边的情况下问你所删掉的边的最小权值和是多少。

【分析】

显然,我们直接按照题意做显然是有点麻烦的,所以我们把问题转化一下,因为要保证最后的图不含环路,所以可以看成最后一定是一棵树或者多棵树,于是我们就直接求一个生成树,也就是最后剩下的边。因为要保证删除的边的权值和最小,也就是我们的生成树的权值最大,于是就可以想到题目就是求一个最大生成树,然后用所有的边权和,然后减去这个最大生成树的权值就是最后的答案,

【代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<sstream>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS_1(a) memset(a,-1,sizeof(a))
#define MSinf(a) memset(a,0x3f,sizeof(a))
#define MSfalse(a) memset(a,false,sizeof(a))
#define inf 0x3f3f3f3f
#define lson i<<1,l,mid
#define rson ((i<<1)|1),mid+1,r
#define uint unsigned int
typedef pair<int,int> PII;
#define A first
#define B second
#define pb push_back
#define mp make_pair
#define ll long long
#define eps 1e-8
inline void read1(int &num) {
    char in;
    bool IsN=false;
    in=getchar();
    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
    if(in=='-') {
        IsN=true;
        num=0;
    } else num=in-'0';
    while(in=getchar(),in>='0'&&in<='9') {
        num*=10,num+=in-'0';
    }
    if(IsN) num=-num;
}
inline void read2(int &a,int &b) {
    read1(a);
    read1(b);
}
inline void read3(int &a,int &b,int &c)
{
    read1(a);
    read1(b);
    read1(c);
}
inline void read1(ll &num) {
    char in;
    bool IsN=false;
    in=getchar();
    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
    if(in=='-') {
        IsN=true;
        num=0;
    } else num=in-'0';
    while(in=getchar(),in>='0'&&in<='9') {
        num*=10,num+=in-'0';
    }
    if(IsN) num=-num;
}
inline void read2(ll &a,ll &b) {
    read1(a);
    read1(b);
}
inline void read3(ll &a,ll &b,ll &c)
{
    read1(a);
    read1(b);
    read1(c);
}
inline void read1(double &num) {
    char in;
    double Dec=0.1;
    bool IsN=false,IsD=false;
    in=getchar();
    while(in!='-'&&in!='.'&&(in<'0'||in>'9'))
        in=getchar();
    if(in=='-') {
        IsN=true;
        num=0;
    } else if(in=='.') {
        IsD=true;
        num=0;
    } else num=in-'0';
    if(!IsD) {
        while(in=getchar(),in>='0'&&in<='9') {
            num*=10;
            num+=in-'0';
        }
    }
    if(in!='.') {
        if(IsN) num=-num;
        return ;
    } else {
        while(in=getchar(),in>='0'&&in<='9') {
            num+=Dec*(in-'0');
            Dec*=0.1;
        }
    }
    if(IsN) num=-num;
}
inline void read2(double &a,double &b)
{
    read1(a);
    read1(b);
}
inline void read3(double &a,double &b,double &c)
{
    read1(a);
    read1(b);
    read1(c);
}
inline void hdu(void)
{
    srand(time(0));
    printf("%d\n",rand()%5217+1000);
}
///-----------------------------------------------------------------------------------
const int maxm = 1e5+10;
struct E
{
    int from,to,value;
}edge[maxm];
bool cmp(E a,E b)
{
    return a.value>b.value;
}
int n,m;
int pre[maxm];
int fin(int ind)
{
    return pre[ind]==ind?ind:(pre[ind]=fin(pre[ind]));
}
void init(int n)
{
    rep1(i,1,n) pre[i] = i;
}
int main(void)
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init(n);
        int a,b;
        while(n--) read2(a,b);
        int ans = 0;
        rep0(i,0,m) 
        {
            read3(edge[i].from,edge[i].to,edge[i].value);
            ans+=edge[i].value;
        }
        sort(edge,edge+m,cmp);
        int ans2 = m;
        rep0(i,0,m)
        {
            a = fin(edge[i].from);
            b = fin(edge[i].to);
            if(a!=b)
            {
                ans2--;
                pre[a] = b;
                ans-=edge[i].value;
            }
        }
        printf("%d %d\n",ans2,ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zuhiul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值