POJ1861

来源:互联网 发布:淘宝如何增加粉丝 编辑:程序博客网 时间:2024/06/05 10:54

Problem: Network
Description: 给你一个图的一些边,让你求一个边集,使得连通所有的点,并且其中最大的边要最小。
Solution: 首先,我们看到连通所有的点,那不就是最小生成树吗。其中最大的边最小,我们可以想到kruskal算法。它就是贪心选边,我一开始想着二分选择那个最小的边。但是后来一想,我们把kruskal中的排序反过来不就可以使得最大的边最后选,这样不就满足了题目的要求吗!太秒了。
Code(C++):

#include <stdio.h>#include <string.h>#include <algorithm>#define MAX(a,b) ((a)>(b)? (a):(b))#define MIN(a,b) ((a)<(b)? (a):(b))const int M=15000+5;const int E=1000+5;using namespace std;typedef struct tagEdge{    int x,y;    int v;    tagEdge(){}    tagEdge(int x,int y,int v)    {        this->x=x;        this->y=y;        this->v=v;    }}Edge;int n,m;Edge edges[M];int p[E];int T;int num;Edge ans[M];bool cmp(Edge a,Edge b){    return a.v<b.v;}int find(int x){    if(p[x]==x)        return x;    return p[x]=find(p[x]);}void work(){    for(int i=0;i<E;i++)        p[i]=i;    num=0;    for(int i=0;i<m;i++){        int px=find(edges[i].x);        int py=find(edges[i].y);        if(px==py)            continue;        ans[num++]=edges[i];        p[px]=py;        T=edges[i].v;        if(num==n-1)            break;    }}int main(){    while(~scanf("%d%d",&n,&m)){        int x,y,v;        for(int i=0;i<m;i++)            scanf("%d%d%d",&x,&y,&v),            edges[i]=Edge(x,y,v);        sort(edges,edges+m,cmp);        work();        printf("%d\n%d\n",T,num);        for(int i=0;i<num;i++)            printf("%d %d\n",ans[i].x,ans[i].y);    }    return 0;}
0 0