说出无向图的欧拉回路的路径
使用Fleury算法
(1)其实就是dfs,标记边,逆序输出
(2)保证字典序最小,则每次拓展边时,优先选择边值较小的即可。
(3)因为是逆序输出,所以保存到stack中,在弹出。
下面是2种边的储存法的解法:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 2010;
struct node{
int z, x, y;
node(){}
node(int z, int x, int y) : z(z), x(x), y(y) {}
bool operator<(const node &a) const
{
return z < a.z;
}
};
vector<node>adj[2010];
int du[55];
stack<int>S;
int vis[2010];
int en, vn, st;
void dfs(int u)
{
for (int r = 0; r < adj[u].size(); r++)
{
if (!vis[adj[u][r].z])
{
int v = adj[u][r].y;
vis[adj[u][r].z] = 1;
dfs(v);
S.push(adj[u][r].z);
}
}
}
int dfs2(int u)
{
vis[u] = 1;
int ret = 1;
for (int r = 0; r < adj[u].size(); r++)
{
int v = adj[u][r].y;
if (!vis[v])
ret += dfs2(v);
}
return ret;
}
void solve()
{
for (int i = 1; i <= vn; i++)
sort(adj[i].begin(), adj[i].end());
memset(vis, 0, sizeof(vis));
int tot = dfs2(st);
for (int i = 1; i <= vn; i++)
if (du[i] % 2) tot = 0;
while (!S.empty()) S.pop();
memset(vis, 0, sizeof(vis));
dfs(st);
if (tot == vn && S.size() == en)
{
int p = 0;
while (!S.empty())
{
if (!p) p = 1;
else printf(" ");
printf("%d", S.top());
S.pop();
}
puts("");
}
else
{
puts("Round trip does not exist.");
}
}
int main()
{
int x, y, z;
while (scanf("%d%d",&x,&y) && (x || y))
{
scanf("%d", &z);
memset(du, 0, sizeof(du));
for (int i = 0; i < 2010; i++)
adj[i].clear();
st = min(x, y);
vn = max(x, y);
en = z;
adj[x].push_back(node(z, x, y));
adj[y].push_back(node(z, y, x));
du[x]++;
du[y]++;
while (scanf("%d%d", &x, &y) && (x || y))
{
scanf("%d", &z);
vn = max(x, vn);
vn = max(y, vn);
en = max(en, z);
adj[x].push_back(node(z, x, y));
adj[y].push_back(node(z, y, x));
du[x]++;
du[y]++;
}
solve();
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 2010;
int du[55];
stack<int>S;
int adj[2010][2];
int vis[2010];
int en, vn, st;
void dfs(int u)
{
for (int i = 1; i <= en; i++)
{
if (!vis[i])
{
int v;
if (adj[i][0] == u) v = adj[i][1];
else if (adj[i][1] == u) v = adj[i][0];
else continue;
vis[i] = 1;
dfs(v);
S.push(i);
}
}
}
int dfs2(int u)
{
vis[u] = 1;
int ret = 1;
for (int i = 1; i <= en; i++)
{
int v;
if (adj[i][0] == u) v = adj[i][1];
else if (adj[i][1] == u) v = adj[i][0];
else continue;
if (!vis[v])
ret += dfs2(v);
}
return ret;
}
void solve()
{
// cout << vn << ' ' << en << ' ' << st << endl;
memset(vis, 0, sizeof(vis));
int tot = dfs2(st);
for (int i = 1; i <= vn; i++)
if (du[i] % 2) tot = 0;
// cout << "^^^^^^^^^^^66" << endl;
// cout << tot << endl;
while (!S.empty()) S.pop();
memset(vis, 0, sizeof(vis));
dfs(st);
// cout << "^^^^^^^^^^^66" << endl;
// cout << S.size() << endl;
if (tot == vn && S.size() == en)
{
int p = 0;
while (!S.empty())
{
if (!p) p = 1;
else printf(" ");
printf("%d", S.top());
S.pop();
}
puts("");
}
else
{
puts("Round trip does not exist.");
}
}
int main()
{
int x, y, z;
while (scanf("%d%d",&x,&y) && (x || y))
{
scanf("%d", &z);
memset(du, 0, sizeof(du));
st = min(x, y);
vn = max(x, y);
en = z;
adj[z][0] = x; adj[z][1] = y;
du[x]++;
du[y]++;
while (scanf("%d%d", &x, &y) && (x || y))
{
scanf("%d", &z);
vn = max(x, vn);
vn = max(y, vn);
en = max(en, z);
adj[z][0] = x; adj[z][1] = y;
du[x]++;
du[y]++;
}
solve();
}
return 0;
}
662

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



