[POI2008]CLO

题面

<center>2026: [POI2008]CLO<center>
<center>时间限制:10秒 内存限制:162MB<center>

题目描述
  Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 你要把其中一些road变成单向边使得:每个town都有且只有一个入度。
输入
  第一行输入n m.1 <= n<= 100000,1 <= m <= 200000 下面M行用于描述M条边.

输出
  TAK或者NIE 常做POI的同学,应该知道这两个单词的了...
样例输入

4 5
1 2
2 3
1 3
3 4
1 4

样例输出

TAK

思路

题解
  首先说一下,我的做题过程。本来以为是一道简单的图论+贪心题,但是却一直wa,百思不得其解……,在网上搜了题解,才明白过来,自己有一个图论的知识点,理解错了:无向边不贡献出度,也不贡献入度but me think 无向边贡献出度,贡献入度
  这道题用并查集做,(建图的话,数据量太大,存储不下),首先,初始化:N个节点,每个建立一个集合,第i个节点所在集合编号为i;然后处理m条边,只要两个节点之间有边,就把他们放到一个集合里面,如果加的边的两个节点在同一个集合里,那么这个集合标记为true(初始所有集合为false);处理完所以边之后,判断:只要有一个集合为false,则ans=NIE;只有所有集合均为true,ans=TAK。

源码

/************并查集***************/
#include<iostream>
#include <cstring>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=1e5+5;
int fa[N];//f[i]表示节点i与谁在一个集合,初始f[i]=i,
//如:f[1]=2,表示1与2在一个集合,但2有可能在其他集合,所以i不一定在集合2
bool can[N];//can[i]表示集合i是否可行,初始值均为false
int find(int x){//核心函数,查找节点x在哪个集合
    if (fa[x]==x)   return x;//在本身集合,直接返回
    fa[x]=find(fa[x]);//在其他集合,看其他集合是否加入新集合,并更新
    return fa[x];//返回所在集合
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n,m,i,x,y,a,b;
    cin>>n>>m;
    mem(can, false);//初始化can[],均为false
    for (i=1;i<=n;i++)  fa[i]=i;//初始化f[],f[i]=i
    for (i=1;i<=m;i++){
        cin>>a>>b;
        x=find(a),y=find(b);//分别查找a,b所在集合
        x!=y?(fa[x]=y,can[y]|=can[x]):can[fa[x]]= true;//若a,b在同一集合,则该集合改为true;
        //否则,将a所在集合x加入b所在集合y,并修改集合y的can值,只要集合x、y有一个为true则该集合为true;
    }
    for (i=1;i<=n;i++){
        if (!can[find(i)]){//只要有一个节点所在集合为false,那么就不行(NIE)
            cout<<"NIE\n";return 0;
        }
    }
    cout<<"TAK\n";//所有节点所在集合为true,才可以(TAK)
    return 0;
}
/*
4 4
1 2
1 3
1 4
2 4
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值