uva 10763 Foreign Exchange

给定n对信息,是1-->2有一对交换生,能交换的条件是2-->1也有一对交换生,问能否顺利交换。

思路:用有向图模拟,如果1-->2有一对,那么就优先判断2-->1有没人交换,有的话,就不用加边了,直接标记那条边用了即可。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 5e5+20;
int n,now;
struct edge
{
    int u,v,w;
    int id;//区分无向图的时候用的,id相同就是同一条边
    int next;
} e[maxn*2]; //这个存的是边,要插入两次,所以要*2
int first[maxn]; //这个表示什么【顶点】的第一条边,所以只用maxn大小即可
int num=0;//从1开始,这样就是没0号这条边。方便判断。所以每次先++num再放边!!
void add (int u,int v,int w)
{
    ++num; //这个num是边的编号
    e[num].u=u;  e[num].v=v;  e[num].w=w;
    e[num].id=0;
    e[num].next=first[u];//下一条边是这个顶点的第一条边
    first[u]=num;//这个顶点的第一条边是编号为num的这条
    return ;
}

void work ()
{
    num = 0;
    now = 0;
    memset(first,0,sizeof first);
    for (int i=1;i<=n;++i)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        bool flag = 1;
        for (int j = first[v]; j ; j = e[j].next)
        {
            if (e[j].v == u && e[j].id == 0)
            {
                flag = 0;
                e[j].id=1;
                now--;
                break;
            }
        }
        if (flag)
        {
            now++;
            add(u,v,1);
        }
    }
    if (now==0)
    {
        printf ("YES\n");
    }
    else printf ("NO\n");
}
int main()
{
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    while (scanf("%d",&n)!=EOF && n) work();
    return 0;
}
View Code

 

posted on 2016-08-19 23:20  stupid_one  阅读(141)  评论(0编辑  收藏  举报

导航