USACO 3.3.1

    这年过的,从回家就没怎么写过东西,今天老爸在用台式机斗地主我就掏出本来写点吧。而且今天意外的发现一个问题之前我一直把USACO 写成了USCAO ……真是2到家了。
    这道题是要求我们求出一条欧拉路,所以我们要首先判断图中是否有欧拉路
  那么关于欧拉图:对于一个无向图,如果它每个点的度都是偶数,那么它存在一条欧拉回路;如果有且仅有2个点的度为奇数,那么它存在一条欧拉路;如果超过2个点的度为奇数,那么它就不存在欧拉路了。

  由于题目中说数据保证至少有1个解,所以一定存在欧拉路了。选起点的时候如果没有点的度为奇数,那么任何一个点都能做起点。如果有2个奇点,那么就只能也这两个点之一为起点,另一个为终点。但是题目要求输出的是进行进制转换之后最小的(也就是输出第一个数较小的,如果还有多组解,输出第二个数较小的,等等),所以我们要以最小的点做起点。

  找出欧拉路的方法就是采用深搜的方式,对于当前的点,把所有点从小到大的搜索,找到和它相连的,找到一个之后删除它们之间的连线,并去搜索新的那个点,如果没有找到点和它相连,那么就把这个点加入输出队列。

  不过我们这么操作之后,顺序是反着的,输出时反着输出即可。

注意两点:一、给出点的序号不一定就是从小到大给出的;二、两个点之间可能有不止一条道路。


#include<fstream>

#include<string.h>

using namespace std;

int Min=1<<30,Max=-1;

int map[505][505];

int deg[505];

int path[10000];

int cnt=0;

void dfs(int t)

{

for(int i=Min;i<=Max;i++)

if(map[t][i])

{

map[t][i]--;

map[i][t]--;

dfs(i);

}

path[cnt++]=t;

}

int main()

{

ifstream fin("fence.in");

ofstream fout("fence.out");

int f,u,v;

fin>>f;

memset(map,0,sizeof(map));

memset(deg,0,sizeof(deg));

for(int i=0;i<f;i++)

{

fin>>u>>v;

if(Min>u)

Min=u;

if(Max<u)

Max=u;

if(Min>v)

Min=v;

if(Max<v)

Max=v;

map[u][v]++;

map[v][u]++;

deg[u]++;

deg[v]++;

}

int i;

for(i=Min;i<=Max;i++)

if(deg[i]%2)

{

u=i;

break;

}

if(i>Max)

u=Min;

dfs(u);

for(i=cnt-1;i>=0;i--)

fout<<path[i]<<endl;

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值