您的位置:首页 > 其它

信与信封问题

2013-08-10 18:51 204 查看

这题目做了我好久,以前从来没做过,现在基础还没打好,代码是网上的,只能说稍微有理解那么一点,如果有什么好的方法解这道题,希望各位能够给点意见

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte

总提交:106            测试通过:41

描述

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,尽可能多地将信正确地装回信封。

输入

本题有多组输入数据,你必须处理到EOF为止。

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

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

输出

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

每组输出结束之后,输出一个空行。

样例输入

3

1 2

1 3

2 1

0 0

样例输出

1 1

#include<iostream>
#include<cstring>
using namespace std;
int tot=0,n,link[105],f[105];
bool map[105][105]={0},v[105];
bool find(int x)
{
int i;
for(i=1;i<=n;i++)
if(!map[x][i]&&!v[i])
{   v[i]=1;
if(link[i]==0||find(link[i])) //找增广路
{  link[i]=x;return true;  }
}
return false;
}
int hungary()
{
int ans=0,i;
memset(link,0,sizeof(link));
for(i=1;i<=n;i++)
{  memset(v,0,sizeof(v));
if(find(i))ans++; //增广成功。
}
return ans;
}
void solve()
{
int i,t; bool flag=1;
t=hungary();
memcpy(f,link,sizeof(link));//记录第一次的匹配情况。
if(t!=n)cout<<"none";
else for( i=1;i<=n;i++)
{
map[f[i]][i]=1;//断边
t=hungary();
if(t!=n){cout<<f[i]<<" "<<i<<endl;flag=0;}
map[f[i]][i]=0;//恢复
}
if(flag)cout<<"none";//输出为空。
}
int main()
{

int i,j,x,y;
cin>>n;
while (1)
{
cin>>x>>y;
if(x+y==0)break;
map[x][y]=1;
}
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: