codevs1222 信与信封问题

1222 信与信封问题

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题目描述 Description

John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出。但是,第二天John的儿子Small John将这n封信都拿出了信封。不幸的是,Small John无法将拿出的信正确地装回信封中了。

将Small John所提供的n封信依次编号为1,2,…,n;且n个信封也依次编号为1,2,…,n。假定Small John能提供一组信息:第i封信肯定不是装在信封j中。请编程帮助Small John,尽可能多地将信正确地装回信封。

输入描述 Input Description

n文件的第一行是一个整数n(n≤100)。信和信封依次编号为1,2,…,n。

n接下来的各行中每行有2个数i和j,表示第i封信肯定不是装在第j个信封中。文件最后一行是2个0,表示结束。

输出描述 Output Description

输出文件的各行中每行有2个数i和j,表示第i封信肯定是装在第j个信封中。请按信的编号i从小到大顺序输出。若不能确定正确装入信封的任何信件,则输出“none”。

样例输入 Sample Input

3

1  2

1  3

2  1

0  0

样例输出 Sample Output

1   1

/*
开始把边取反,然后跑一边匈牙利算法,然后判断是不是完美匹配(概念网上自己去找),不是就直接输出none;
第二步每次删掉一条边,判断是不是完美匹配,不是就输出这个两个点;
第二步跑完之后没有发现有一个是可以输出的,就输出none;
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>

#define N 555

using namespace std;
int mx[N],Li[N],head[N];
int n,cut_x,cut_y,S[N],T[N],num,flag=0;
bool vis[N],k[N][N];
struct node
{
    int u;
    int to;
    int next;
} e[N<<1];

void add(int u,int to)
{
    e[++num].to=to;e[num].next=head[u];head[u]=num;
}

int dfs(int x)
{
    int v;
    for (int i=head[x];i!=0;i=e[i].next)
    {
        v=e[i].to;
        if(x==cut_x && v==cut_y) continue;
        if(vis[v]==true) continue;
        vis[v]=true;
        if(Li[v]==0 || dfs(Li[v]) )
        {
            mx[x]=v;
            Li[v]=x;
            return 1;
        }
    }
    return 0;
}

int maxmatch()
{
    int ans=0;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++) vis[j]=false;
        ans+=dfs(i);
    }
    return ans;
}

void Impotant_edge()
{
    int ans;
    for (int i=1;i<=n;i++)
    {
        S[i]=i;T[i]=mx[i];
    }
    for (int i=1;i<=n;i++)
    {
        cut_x=S[i];cut_y=T[i];
        for (int j=1;j<=n;j++) mx[j]=0,Li[j]=0;
        ans=maxmatch();
        if (ans!=n)
        {
            printf("%d %d\n",cut_x,cut_y);
            flag=1;
        }
    }
    return;
}

int main()
{
    int ans,x,y;
    scanf("%d",&n);
    while(1)
    {
        scanf("%d%d",&x,&y);
        if (x==0&&y==0) break;
        k[x][y]=1;
    }
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if( k[i][j]==0 ) add(i,j);
    ans=maxmatch();
    if (ans!=n)
    {
        cout<<"none"<<endl;
        return 0;
    }
    else
    {
        Impotant_edge();
        if (flag==0)  cout<<"none"<<endl;
        return 0;
    }
}
时间: 2024-10-11 07:47:26

codevs1222 信与信封问题的相关文章

codevs1222 信与信封的问题

题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯定不是装在信封j中.请编程帮助Small John,尽可能多地将信正确地装回信封. 输入描述 Input Des

CODEVS1222 信与信封问题 (匈牙利算法)

先做一遍匈牙利算法.对于已经匹配的边,如果删去之后还能最大匹配数增加,则不符合要求. 一遍匈牙利算法是O(n^3)的,对于每一条边做n次,每次O(n^2),总的复杂度是O(n^3). 注意:不要忘记输出none. 1 var a:array[0..1000,0..1000] of boolean; 2 l,r:array[0..1000] of longint; 3 pd:array[0..1000] of boolean; 4 i,j,x,y,n,sum,num:longint; 5 func

codevs 1222 信与信封问题(二分图的完美匹配)

1222 信与信封问题 题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯定不是装在信封j中.请编程帮助Small John,尽可能多地将信正确地装回信封. 输入

WIKIOI 1222信与信封问题

题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯定不是装在信封j中.请编程帮助Small John,尽可能多地将信正确地装回信封. 输入描述 Input Des

codevs 1222 信与信封问题

/* 二分图 题目给出的是确定不连通的边 如果我们剩下的可能联通也可能不连通的 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 210 using namespace std; int n,num,head[maxn],g[maxn][maxn],ans,f[maxn],match[maxn],sum,ei; struct An

CodeVS 1697-⑨要写信

原题 题目描述 Description 琪露诺(冰之妖精)有操控冷气的能力.能瞬间冻结小东西,比普通的妖精更危险.一直在释放冷气的她周围总是非常寒冷. 由于以下三点原因-- 琪露诺的符卡 冰符"Icicle Fall"-Easy的弹幕有够蠢的,只要站在她的正前方就没任何弹幕会碰到你: ZUN在<红魔乡>中介绍她时已经说她有点笨笨的了: 在ZUN放出<东方花映冢>的介绍图时,在图中把琪露诺放在了⑨的位置上,并以"⑨笨蛋"简单带过,从此"

第 7 章 门面模式【Facade Pattern】

以下内容出自:<<24种设计模式介绍与6大设计原则>> 好,我们继续讲课.大家都是高智商的人,都写过纸质的信件吧,比如给女朋友写情书什么的,写信的过程大家都还记得吧,先写信的内容,然后写信封,然后把信放到信封中,封好,投递到信箱中进行邮递,这个过程还是比较简单的,虽然简单,这四个步骤都是要跑的呀,信多了还是麻烦,比如到了情人节,为了大海捞针,给十个女孩子发情书,都要这样跑一遍,你不要累死,更别说你要发个广告信啥的,一下子发1 千万封邮件,那不就完蛋了?那怎么办呢?还好,现在邮局开发

设计模式之五-Facade模式

Facade门面模式,也是比较常用的一种模式,其含义是为子系统中的一组接口提供一个一致的界面, Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.简单说,就是将复杂的逻辑封装起来,对外公开简单的接口,由客户程序调用. 以收发信件和警察检查实例为例 说明:邮局对外只有一个窗口,接收信件内容和邮件地址.对内调用邮件处理的4个函数.将复杂逻辑封装在邮局的里面,当需要增加警察来检查信件时,只需在邮局内增加警察检查信件的方法. 注意:将复杂逻辑封装起来,对外只有一个简单的接口. 抽

《程序设计中的组合数学》——全错位排列

承接上文,这次以递推的思维,介绍组合学当中一个很经典的问题. 这个问题最开始由瑞士数学家欧拉提出,原始的问题被叫做“装信封问题”,问题的大意就是:有n封信和n封它们各自对应的信封,如果邮递员想要把每封信都放在不属于这封信的信封,那么请问有多少种排法.(这邮递员真无聊)  想必这个问题在中学阶段数学的[排列组合]都有过接触,但是我记忆非常深刻的是,老师讲到这个模型,自己找了一下n = 5的情况就停止了,然后让大家把前面的数字序列背下来.今日故地重游不禁觉得老师教的好坑爹,搞学习还是要亲历亲为自主探