John's trip
2014-03-22 20:07
211 查看
题目链接
题意:
输入a、b、c,表示点a和点b之间有一条边,边序号为c,现在让从第一次输入的两个点中较小的点(这里题意是个坑),走过所有的边后必须回到起点,输出最小路径
关键:
欧拉回路+输出路径(边序号)
const int MAXN = 2100;
const int MAXV = 2000;
const int MAXE = 2020 * 2;
struct Edge
{
int from, to, id;
};
struct UnDirect_Euler
{
int n, m;
int deg[MAXV];
bool vis[MAXE];
vector<int> G[MAXV];
vector<Edge> edges;
stack<int> sk;
vector<int> ans;
void init(int n)
{
this->n = n;
edges.clear();
REP(i, n)
{
deg[i] = 0;
G[i].clear();
}
}
void addEdge(int a, int b, int id)
{
edges.push_back((Edge) { a, b, id });
edges.push_back((Edge) { b, a, id });
m = edges.size();
G[a].push_back(m - 2);
G[b].push_back(m - 1);
deg[a]++;
deg[b]++;
}
void dfs(int u, int ind)
{
REP(i, G[u].size())
{
int x = G[u][i];
Edge& e = edges[x];
if (!vis[x])
{
vis[x] = vis[x ^ 1] = true;
dfs(e.to, x);
}
}
if (ind >= 0)
sk.push(ind);
}
//返回1:欧拉回路 返回2:欧拉路经
int solve(int s)
{
ans.clear();
int cnt = 0;
REP(i, n)
{
if (deg[i] == 1)
{
if (++cnt > 2) return 0;
s = i;
}
else if (deg[i] % 2 != 0) return 0;
}
while (!sk.empty()) sk.pop();
REP(i, m) vis[i] = false;
dfs(s, -1);
REP(i, m) if (!vis[i]) return 0;
while (!sk.empty())
{
ans.push_back(sk.top());
sk.pop();
}
return cnt != 0 ? 1 : 2;
}
} graph;
struct Node
{
int a, b, c;
int operator< (const Node& rhs) const
{
return c < rhs.c;
}
} ipt[MAXN];
int read()
{
graph.init(MAXV);
int n;
for (n = 0;;n++)
{
RII(ipt
.a, ipt
.b);
if (ipt
.a == 0)
break;
RI(ipt
.c);
}
sort(ipt, ipt + n);
REP(i, n)
graph.addEdge(ipt[i].a, ipt[i].b, ipt[i].c);
return n;
}
int main()
{
// freopen("in.txt", "r", stdin);
while (read())
{
int start = min(ipt[0].a, ipt[0].b);
if (graph.solve(start))
{
vector<int>& ans = graph.ans;
REP(i, ans.size())
{
printf("%d%c", graph.edges[ans[i]].id, i == (int)ans.size() - 1 ? '\n' : ' ');
}
}
else
{
puts("Round trip does not exist.");
}
}
return 0;
}
题意:
输入a、b、c,表示点a和点b之间有一条边,边序号为c,现在让从第一次输入的两个点中较小的点(这里题意是个坑),走过所有的边后必须回到起点,输出最小路径
关键:
欧拉回路+输出路径(边序号)
const int MAXN = 2100;
const int MAXV = 2000;
const int MAXE = 2020 * 2;
struct Edge
{
int from, to, id;
};
struct UnDirect_Euler
{
int n, m;
int deg[MAXV];
bool vis[MAXE];
vector<int> G[MAXV];
vector<Edge> edges;
stack<int> sk;
vector<int> ans;
void init(int n)
{
this->n = n;
edges.clear();
REP(i, n)
{
deg[i] = 0;
G[i].clear();
}
}
void addEdge(int a, int b, int id)
{
edges.push_back((Edge) { a, b, id });
edges.push_back((Edge) { b, a, id });
m = edges.size();
G[a].push_back(m - 2);
G[b].push_back(m - 1);
deg[a]++;
deg[b]++;
}
void dfs(int u, int ind)
{
REP(i, G[u].size())
{
int x = G[u][i];
Edge& e = edges[x];
if (!vis[x])
{
vis[x] = vis[x ^ 1] = true;
dfs(e.to, x);
}
}
if (ind >= 0)
sk.push(ind);
}
//返回1:欧拉回路 返回2:欧拉路经
int solve(int s)
{
ans.clear();
int cnt = 0;
REP(i, n)
{
if (deg[i] == 1)
{
if (++cnt > 2) return 0;
s = i;
}
else if (deg[i] % 2 != 0) return 0;
}
while (!sk.empty()) sk.pop();
REP(i, m) vis[i] = false;
dfs(s, -1);
REP(i, m) if (!vis[i]) return 0;
while (!sk.empty())
{
ans.push_back(sk.top());
sk.pop();
}
return cnt != 0 ? 1 : 2;
}
} graph;
struct Node
{
int a, b, c;
int operator< (const Node& rhs) const
{
return c < rhs.c;
}
} ipt[MAXN];
int read()
{
graph.init(MAXV);
int n;
for (n = 0;;n++)
{
RII(ipt
.a, ipt
.b);
if (ipt
.a == 0)
break;
RI(ipt
.c);
}
sort(ipt, ipt + n);
REP(i, n)
graph.addEdge(ipt[i].a, ipt[i].b, ipt[i].c);
return n;
}
int main()
{
// freopen("in.txt", "r", stdin);
while (read())
{
int start = min(ipt[0].a, ipt[0].b);
if (graph.solve(start))
{
vector<int>& ans = graph.ans;
REP(i, ans.size())
{
printf("%d%c", graph.edges[ans[i]].id, i == (int)ans.size() - 1 ? '\n' : ' ');
}
}
else
{
puts("Round trip does not exist.");
}
}
return 0;
}
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- 封装好的Folyd建图,C++源码
- zoj3549 快速幂
- 浅谈manacher算法 最长回文子串(Longest Palindromic Substring)
- 前缀表达式,中缀表达式,后缀表达式转化和计算
- c/c++中让输入以回车换行键结束输入
- 图论学习笔记之一——Floyd算法
- NWERC2010 NKOJ2178 Stock Prices
- 2011ACM福州网络预选赛B题 HDU4062 Abalone
- Codeforces Round #197 (Div. 2)
- Codeforces Round #198 (Div. 1)
- Dijkstra算法