CSUOJ--1633 Landline Telephone Network

来源:互联网 发布:高性能网络编程框架 c 编辑:程序博客网 时间:2024/06/05 04:44

其实就是一道最小生成树的题目.我们只需要将坏点排除在外,然后对其它点做一次最小生成树,然后在将坏点连接到这颗生成树上(每次都选代价最小的点).当然如果最后不是所有的点都连接到一起,就是impossible了.
还有一种情况需要特判,就是如果一共只有两个点,并且都是坏点,这种情况也是合法的.

代码如下:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;#define maxn 210000#define ll long long#define INF 0x3f3f3f3fvector<int>g[maxn],w[maxn];typedef struct{    int x,y,w;}P;P p[maxn];int cmp(P p1,P p2){    return p1.w<p2.w;}int e,fa[maxn];int a[maxn],flag[maxn];int Find(int x){     return fa[x]==x?x:Find(fa[x]);}///如果只有两个点,且全部是坏点则要特判int main(){      int n,m,k;     // freopen("in.txt","r",stdin);      while(scanf("%d%d%d",&n,&m,&k)!=EOF)      {              int h;              memset(flag,0,sizeof(flag));              for(int i=1;i<=n;i++)                  fa[i]=i;              for(int i=1;i<=n;i++)                 g[i].clear(),w[i].clear();              for(int i=0;i<k;i++)              {                    scanf("%d",&a[i]);                    flag[a[i]]=1;              }              e=0;              for(int i=1;i<=m;i++)              {                    int x,y,z;                    scanf("%d%d%d",&x,&y,&z);                    if(k==2&&x==a[0]&&y==a[1]) h=z;                    if(k==2&&y==a[0]&&x==a[1]) h=z;                    p[e].x=x; p[e].y=y; p[e].w=z; e++;                    p[e].x=y; p[e].y=x; p[e].w=z; e++;                    g[x].push_back(y); w[x].push_back(z);                    g[y].push_back(x); w[y].push_back(z);              }              if(n==2&&k==2)              {                    printf("%d\n",h);                    continue;              }              sort(p,p+e,cmp);              int cnt=1;              bool bl=true;              ll ans=0;              for(int i=0;i<e;i++)              {                   int x=p[i].x,y=p[i].y;                   if(!flag[x]&&!flag[y])                   {                         int xx=Find(x);                         int yy=Find(y);                         if(xx!=yy)                         {                              ans+=p[i].w; cnt++;                              fa[xx]=yy;                         }                   }              }              if(cnt<n-k)  bl=false;              int sum1=0,sum2=0;              for(int i=0;i<k;i++)              {                     int x=a[i],y,tmp=INF;                     for(int j=0;j<g[x].size();j++)                     {                           y=g[x][j];                           if(flag[y])                              continue;                           if(tmp>w[x][j])                               tmp=w[x][j];                     }                     if(tmp<INF)                        ans+=tmp,cnt++;              }              if(cnt<n) bl=false;              if(!bl)                  printf("impossible\n");              else                  printf("%lld\n",ans);      }   return 0;}
1 0
原创粉丝点击