哈理工 校赛(热身)2238 围巾的纠结


围巾的纠结


Time Limit: 500 MS


Memory Limit: 32768 K


Total Submit: 123(52 users)


Total Accepted: 57(48 users)


Rating:


Special Judge: No


Description


小破想要织一条围巾,可是她并不擅长于织围巾。由于工作太忙,每天她都只能织一点。为了快速的织完围巾,她决定直接把毛线球连在一起。围巾上有球球还是非常可爱的嘛~

于是小破去商店买了n个毛线球。每天晚上睡觉之前,她就抽出一点时间,把其中两个原本分开的毛线球织在一起。由于是睡觉之前干活,人太困了,过了m天之后,她发现自己完全织乱了,于是她决定拆掉重织。可是由于她的织法过于特殊,她发现,一旦几个毛线球被织成了一个圈,就不能完好的解开了。现在她想知道,她还能把这条"围巾"还原吗?


Input


多组测试数据

每组测试数据第一行有两个整数n,m(1 <= n <= 10000, 1 <= m <= 1000000)

接下来有m行,每行有两个数a,b,表示将a和b号毛球织到一起。


Output


对于每组测试数据,如果她能还原,则输出"YES", 否则输出"NO"


Sample Input


5 4

1 2

2 3

3 1

1 4

5 4

1 2

2 3

3 4

4 5


Sample Output


NO

YES


Source


哈尔滨理工大学第五届ACM程序设计竞赛(热身)

话说 何止围巾的纠结?!!用了好几种方法都超内存,最后习得并查集判断无向图回路问题。分分秒解决~。

先来看看这种超时的经典算法:

按照算法描述写出来也是不容易啊。

#include<iostream>
#include<string.h>
#include<set>
#include<queue>
using namespace std;
const int M=10010;
int graph[M][M];
int digree[M];

int main()

{
    int n,m;
    while(cin>>n>>m,n+m)
    {
        memset(graph,0,sizeof(graph));
        memset(digree,0,sizeof(digree));
        for(int i=1; i<=m; i++)
        {
            int a,b;
            cin>>a>>b;
            if(!graph[a][b]&&!graph[b][a])//防止有重边,导致各定点度数变大。
            {
                graph[a][b]=1;添加双向边
                graph[b][a]=1;
                digree[b]++;
                digree[a]++;
            }
        }
        queue<int>q;
        set<int>dict;
        for(int j=1; j<=n; j++)
        {
            if(digree[j]==0||digree[j]==1)//因为图的子图是一个回路,那么每个顶点度数大于等于2,所以删除读数为0和1的结点
            {
                q.push(j);
            }
        }

        while(!q.empty())
        {
            int cur=q.front();
            dict.insert(cur);
            q.pop();
            for(int k=1; k<=n; k++)
            {
                if(graph[cur][k])
                {
                    graph[k][cur]=0;//删除这个结点和所在的边
                    graph[cur][k]=0;
                    digree[k]--;    //同时相连的结点度数减1
                    if(digree[k]==0||digree[k]==1)//判断是否这个顶点可以删除
                        q.push(k);
                }
            }
        }

        if(dict.size()!=n)  //如果每个顶点都进入过队列,则说明可以全部删除,反之则反,另外不能用count记录撤出队列元素个数
            cout<<"NO"<<endl;//来判断(!);
        else
            cout<<"YES"<<endl;
    }
    return 0;
}
/*
5 5
2 1
1 2
2 3
3 4
4 5
 */

如果使用并查集原理,每次往图中加入一条边之前判断两个短点是否属于不同的连通块儿,如果是,那么可以合并,否则必然存在回路。

#include<iostream>
#include<string.h>
using namespace std;
const int M=50001;
int F[M];

int Find(int x)
{
    if(x!=F[x])
        return F[x]=Find(F[x]);
}

bool Is_same(int x,int y)
{
    return Find(x)==Find(y);
}

void union_set(int x , int y)
{
    int tx=Find(x);
    int ty=Find(y);
    if(tx!=ty)
    {
        F[tx]=ty;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        int flag=0;
        for(int j=0;j<M;j++)
            F[j]=j;
        for(int i=0;i<m;i++)
        {
            int a,b;
            cin>>a>>b;
            if(Is_same(a,b))
            flag=1;
            union_set(a,b);
        }
        if(flag)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    }
    return 0;
}
时间: 2024-10-28 05:47:17

哈理工 校赛(热身)2238 围巾的纠结的相关文章

CSU 1425 NUDT校赛 I题 Prime Summation

这个题本来有希望在比赛里面出了的 当时也想着用递推 因为后面的数明显是由前面的推过来的 但是在计算的时候 因为判重的问题 ...很无语.我打算用一个tot[i]来存i的总种树,tot[i]+=tot[j]//j为可以由j推到i的一系列数,但这样是不对的,会产生大量重复计算... 看了下标程才发现要用二维来计算出种类总数,f[i][j]+=sum(f[i-j][k]) 表示在推i数的时候,第一个素数为j的种类数,注意j一定为素数,而且k不能大于j...标程里面处理的比较简练,就学了下他的写法. 至

校赛总结

写写校赛总结....... 这两次校赛是我们组队以后第一次的比赛...第一场打得很拙,第二场还可以吧,第一场校赛--毕竟是期待了很久的校赛,所以感觉还是很紧张,吃饭的时候打了二两,剩了一大半==, 这次我们队名叫 I_Love_High_Math......没走到现场,就快下雨了,真的有点郁闷==.到了以后下雨了,和一个队友被困雨中,,出来以后衣服湿了,一开始就悲剧了...     然后一开场就感觉不好.比赛开始的时候,我去写头文件,然后W说A是水题,然后叫我写,平时都是我写第一题的这次我不想开

NYOJ-682 小媛在努力 (郑大第六届校赛 模拟)

链接:click here 题意: 描述 在多媒体数据处理中,数据压缩算法尤为重要.小媛上完课后就想自己发明一个数据压缩算法.她想呀想,终于想到一个方法.在多媒体数据中有很多数据都是重复的,所以她想把连续相同的数据用数据出现的次数和数据本身表示.例如:1 1 1 2 3 3 3 3 3  压缩后及为3 1 1 2 5 3(表示3个1,1个2和5个3).有想法后小媛就希望把它用代码实现了.但是大家都知道小媛现在整天都忙着苦B的复习考研,连电脑都摸不到.所以她希望作为ACMer的你帮她写一下. 输入

HDU多校赛第9场 HDU 4965Fast Matrix Calculation【矩阵运算+数学小知识】

难度上,,,确实,,,不算难 问题是有个矩阵运算的优化 题目是说给个N*K的矩阵A给个K*N的矩阵B(1<=N<=1000 && 1=<K<=6),先把他们乘起来乘为C矩阵,然后算C^(N*N) 相当于 ABABABABABABAB...=(AB)^(N*N) 不如 A(BA)^(N*N-1)B 因为BA乘得K*K的矩阵,K是比较小的 #include <cstdio> #include <cstdlib> #include <cstr

ZJU校赛 一道计数题

题意是这样的 给定一个n*m的整数矩阵 n和m均小于1000 对这个矩阵删去任意行和列后剩余一个矩阵为M{x1,x2,,,,xm;y1,y2,,,,,yn}表示删除任意的M行N列 对于这个剩下的矩阵,我们考虑其中是否存在特殊的元素,保证这些元素是所在行最大,所在列最小的元素 且非之一. 求对于所有删法,上述元素个数之和 对10^9+7取余. 显然所有删法 有2^(n+m)种 暴力是搞不定的. 于是反过来看,矩阵的元素最多有10^6个 是不是可以考虑每一个元素对最终答案的贡献? 所谓贡献,就是它在

山科第三届校赛总结

这次山科的校赛算是省赛前的一次正式的检验吧,暴露了我们队伍之前训练很多没发现的问题. 比赛的过程真的算是有惊无险,差点就GG... 我们入场晚了一会,我刚读完C题,就发现已经有人过了F题了,我去看F题,是个统计闰年的水题,很快就敲过了.回去想接着看C,感觉也很水,这时cerberux说这个用个map就A了,我让他来敲,可是他好像用的不是很熟练,这道题敲的很慢,交上去还wa了...我回过头仔细看这题,觉得扫一遍统计一次最多连续出现的次数就可以了,这才把这个水题过了.然后我去敲G,G题我出现了很严重

BZOJ 3093: [Fdu校赛2012] A Famous Game

3093: [Fdu校赛2012] A Famous Game Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 242  Solved: 129[Submit][Status][Discuss] Description Mr. B and Mr. M like to play with balls. They have many balls colored in blue and red. Firstly, Mr. B randomly picks

[第十届校赛]简单总结

这次校赛其实是抱着比较大的期望来打的,首先我是单挑,好像自从去年蓝桥杯后就没有一个人做过比赛,一般都是组队做,这次单挑,是想测测自己的水平和对节奏的把握,也有夺冠的冲动,很可惜,整体上是失败了TAT.如果一开始就稳扎稳打,说不定真的可以题数碾压.. 做完胡老师出的三个水题后,交了一发卡精度的二分,节奏就开始乱了.首先我自认为我的思路很正确,并且已经将误差降到很低了,但陆陆续续wa了7发,wa的原因自然是精度问题.大概比赛结束前2个小时,我把精度加大了一位,居然奇迹般的过了,无语..我一直以为比目

青岛理工交流赛 H题 素数间隙

13110581088注销 素数间隙 Time Limit: 1000MS Memory limit: 262144K 题目描述 Neko猫是一个很喜欢玩数字游戏的会说话的肥猫,经常会想到很多很好玩的数字游戏,有一天,它想到一个叫做素数间隙的游戏.据Neko猫的定义,素数间隙是两个相邻素数p和q组成的开区间[p, q),所以素数间隙的长度就是q-p. 例如7和11在素数表里是两个相邻的素数,所以7和11的素数间隙的长度为11-7,为4. 现在Neko猫会给你很多个正整数K(1<K≤1299710