小希的礼物

来源:互联网 发布:蓝牙耳机配对软件 编辑:程序博客网 时间:2024/04/29 17:57

点击打开链接


这个题显然是用并查集解决的,不过我想试试用图论的方法怎么写,首先所有的顶点要连通,然后图无环,然后无重边,无自环,首先判断重边,map映射一下就可以了,确定无重边之后就用bfs判断连通,复杂度O(m),如果连通,然后通过拓扑序列判断环,如果无环,则图是一棵树,输出yes,任何一个环节出错,输出no.

下面是我的冗长但是简单的代码。

#include <set>#include <map>#include <queue>#include <string>#include <bitset>#include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int maxn=100005;const int maxm=2*maxn;struct Pair {    int u,v;    bool operator==(const Pair &t) const{        return u==t.u && v==t.v;    }    bool operator <(const Pair &t) const {        if(u<t.u) return true;        if(u==t.u && v<t.v) return true;        return false;    }};map<Pair,int> mp;int du[maxn];bool vis[maxn];int nodeNum;struct Edge {    int from,to,next;};int pre[maxn];Edge e[maxm];int edgeNum=0;queue<int> q;queue<int> bq;int visit[maxn];void Insert(int from,int to,int i){    e[i].from=from; e[i].to=to; e[i].next=pre[from]; pre[from]=i;}bool bfs(int rt){    while(!bq.empty()) bq.pop();    bq.push(rt);    memset(visit,0,sizeof(visit));    visit[rt]=1;    int k=0;    while(!bq.empty())    {        int t=bq.front();bq.pop(); k++;        for(int i=pre[t];i!=-1;i=e[i].next)        {            int x=e[i].to;            if(visit[x]) continue;            bq.push(x);            visit[x]=1;        }    }    if(k==nodeNum)        return true;    else        return false;}bool top(){    while(!q.empty()) q.pop();    int rt=-1;    for(int i=0;i<maxn;i++)    {        if(vis[i] && du[i]==1) {            q.push(i);        }        if(vis[i]&&rt==-1)        {            rt=i;        }    }    //cout<<rt<<endl;    if(!bfs(rt))        return false;    int k=0;    while(!q.empty())    {        int t=q.front(); q.pop(); k++;        for(int i=pre[t];i!=-1;i=e[i].next)        {            int x=e[i].to;            du[x]--;            if(du[x]==1)                q.push(x);        }    }    if(k==nodeNum)        return true;    else        return false;}int main(){    freopen("input.txt","r",stdin);    int first,second;    while(scanf("%d%d",&first,&second))    {        mp.clear();        memset(du,0,sizeof(du));        memset(vis,0,sizeof(vis));        memset(pre,-1,sizeof(pre));        edgeNum=nodeNum=0;        if(first==-1 && second==-1)            break;        if(first==0 && second==0)        {            printf("Yes\n"); continue;        }        Pair temp; temp.u=first; temp.v=second;        mp.insert(pair<Pair,int>(temp,1));        if(!vis[first]) { nodeNum++; vis[first]=1; }        if(!vis[second]) { nodeNum++; vis[second]=1; }        du[first]++; du[second]++;        Insert(first,second,edgeNum++);        Insert(second,first,edgeNum++);        bool chong=false;        while(scanf("%d%d" ,&first,&second))        {            if(first==0 && second==0) break;            if(chong) continue;            temp.u=first; temp.v=second;            if(mp.count(temp)!=0)            {                chong=true; continue;            }            else            {                mp.insert(pair<Pair,int>(temp,1));                if(!vis[first]) { nodeNum++; vis[first]=1; }                if(!vis[second]) { nodeNum++; vis[second]=1; }                du[first]++; du[second]++;                Insert(first,second,edgeNum++);                Insert(second,first,edgeNum++);            }        }        if(chong)            printf("No\n");        else        {            if(top())                printf("Yes\n");            else                printf("No\n");        }    }    return 0;}


0 0