题目背景
Farmer John 每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。
题目描述
John 是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。
John 的农场上一共有 mm 个栅栏,每一个栅栏连接两个顶点,顶点用 11 到 500500 标号(虽然有的农场并没有那么多个顶点)。一个顶点上至少连接 11 个栅栏,没有上限。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。John 能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。
你需要求出输出骑马的路径(用路上依次经过的顶点号码表示),使每个栅栏都恰好被经过一次。如果存在多组可行的解,按照如下方式进行输出:如果把输出的路径看成是一个 500500 进制的数,那么当存在多组解的情况下,输出 500500 进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,以此类推)。
输入数据保证至少有一个解。
输入格式
第一行一个整数 mm,表示栅栏的数目。
从第二行到第 (m+1)(m+1) 行,每行两个整数 u,vu,v,表示有一条栅栏连接 u,vu,v 两个点。
输出格式
共 (m+1)(m+1) 行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。
数据保证至少有一组可行解。
输入输出样例
输入 #1复制
9 1 2 2 3 3 4 4 2 4 5 2 5 5 6 5 7 4 6
输出 #1复制
1 2 3 4 2 5 4 6 5 7
说明/提示
对于 100%100% 的数据,1≤m≤1024,1≤u,v≤5001≤m≤1024,1≤u,v≤500。
题目翻译来自NOCOW。
USACO Training Section 3.3
//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<list>
#include<set>
#include<iomanip>
#include<cstring>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cassert>
#include<sstream>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
const int MAXN = 305;
const int INF = 0x3f3f3f3f;
const int N=5e4+7;
const int maxn=1e5+5;
const double EPS=1e-10;
const double Pi=3.1415926535897;
//inline double max(double a,double b){
// return a>b?a:b;
//}
//inline double min(double a,double b){
// return a<b?a:b;
//}
int xd[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int yd[8] = {1, 0, -1, 0, -1, 1, -1, 1};
//void Fire(){
// queue<node> p;
// p.push({fx,fy,0});
// memset(fire, -1, sizeof(fire));
// fire[fx][fy]=0;
// while(!p.empty()){
// node temp=p.front();
// p.pop();
// for(int i=0;i<8;i++){
// int x=temp.x+xd[i];
// int y=temp.y+yd[i];
// if(x<0||x>=n||y<0||y>=m||fire[x][y]!=-1){
// continue;
// }
// fire[x][y]=temp.val+1;
// p.push({x,y,temp.val+1});
// }
// }
//}
//int bfs(){
// queue<node> p;
// memset(vis, 0, sizeof(vis));
// p.push({sx,sy,0});
// while (!p.empty()) {
// node temp=p.front();
// vis[temp.x][temp.y]=1;
// p.pop();
// for(int i=0;i<4;i++){
// int x=temp.x+xd[i];
// int y=temp.y+yd[i];
// if(x<0||x>=n||y<0||y>=m) continue;
// if(x==ex&&y==ey&&temp.val+1<=fire[x][y]) return temp.val+1;
// if(vis[x][y]||temp.val+1>=fire[x][y]||a[x][y]=='#') continue;
// p.push({x,y,temp.val+1});
// }
// }
// return -1;
//}
int n,m;
int a[10010][10010];
int lu[100010];
int dgree[100010];
int top;
void dfs(int u){
for(int i=1;i<=n;i++){
if(a[u][i]){
a[u][i]--;
a[i][u]--;
dfs(i);
}
}
lu[++top]=u;
}
int main(){
cin>>m;
int u,v;
for(int i=1;i<=m;i++){
cin>>u>>v;
a[u][v]++;
a[v][u]++;
n=max(n,v);
n=max(n,v);
dgree[u]++;
dgree[v]++;
}
int s=1;
for(int i=1;i<=n;i++){
if(dgree[i]%2){
s=i;
break;
}
}
dfs(s);
while (top) {
cout<<lu[top--]<<endl;
}
}
331



被折叠的 条评论
为什么被折叠?



