• Welcome Party ZOJ


    题目链接:

    Welcome Party

     ZOJ - 4109 

    题目大意:给你T组测试样例,然后n个人,m个关系,每一个关系包括两个人,这两个人为好朋友,然后问你怎么安排顺序,使得整个队伍的友情损失度最小(当一个人放置时,如果他的前面中没有他的朋友,那么整个队伍的朋友损失度就会加1)

    具体思路:首先用并查集求出每一个联通块,然后用一个超级汇点连向这些连通块的根,然后优先队列+bfs求出字典序最小的正解就可以了。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define inf 0x3f3f3f3f
     4 # define ll long long
     5 const int maxn = 2e6+100;
     6 int father[maxn];
     7 vector<int>Edge[maxn];
     8 vector<int>sto;
     9 int vis[maxn];
    10 int Find(int t)
    11 {
    12     return t==father[t]?t:father[t]=Find(father[t]);
    13 }
    14 void mege(int st,int ed)
    15 {
    16     int t1=Find(st);
    17     int t2=Find(ed);
    18     if(t1==t2)return ;
    19     if(t1>t2)swap(t1,t2);
    20     father[t2]=t1;
    21 }
    22 void bfs(int root)
    23 {
    24     priority_queue<int,vector<int>,greater<int> >q;
    25     while(!q.empty())q.pop();
    26     q.push(root);
    27     vis[root]=1;
    28     while(!q.empty())
    29     {
    30         int top=q.top();
    31         q.pop();
    32     //    if(top!=0)
    33         sto.push_back(top);
    34         for(int i=0; i<Edge[top].size(); i++)
    35         {
    36             int to=Edge[top][i];
    37             if(vis[to])
    38                 continue;
    39             vis[to]=1;
    40             q.push(to);
    41         }
    42     }
    43 }
    44 int main()
    45 {
    46     int T;
    47     scanf("%d",&T);
    48     while(T--)
    49     {
    50         int n,m,st,ed;
    51         scanf("%d %d",&n,&m);
    52         sto.clear();
    53         for(int i=0; i<=n; i++)//注意从0开始清空
    54         {
    55             father[i]=i;
    56             Edge[i].clear();
    57             vis[i]=0;
    58         }
    59         for(int i=1; i<=m; i++)
    60         {
    61             scanf("%d %d",&st,&ed);
    62             Edge[st].push_back(ed);
    63             Edge[ed].push_back(st);
    64             mege(st,ed);
    65         }
    66         int ans=0;
    67         for(int i=1; i<=n; i++)
    68         {
    69             if(Find(i)!=i)
    70                 continue;
    71             Edge[0].push_back(i);
    72             ans++;
    73         }
    74         bfs(0);
    75         printf("%d
    ",ans);
    76         for(int i=1; i<sto.size(); i++)
    77         {
    78             if(i==1)
    79                 printf("%d",sto[i]);
    80             else
    81                 printf(" %d",sto[i]);
    82         }
    83         printf("
    ");
    84     }
    85     return 0;
    86 }

     

  • 相关阅读:
    两个栈实现一个队列
    DacningLinks实现
    boost::implicit_cast
    hibernate查询之Criteria实现分页方法(GROOVY语法)
    VS2015 android 设计器不能可视化问题解决。
    当Eclipse爱上SVN
    你不知道的getComputedStyle
    推荐的软件
    React之表单
    理解javascript中的Function.prototype.bind
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10804321.html
Copyright © 2020-2023  润新知