您的位置:首页 > 其它

hdu5424 Rikka with Graph II

2015-09-05 19:59 309 查看
给一个n个节点n条边的无向图G,试判断图中是否存在哈密顿路径。

若G中存在哈密顿路径l,则路径端点度数不小于1,其余点度数不小于2。

则G存在哈密顿路径的必要条件:

1)G连通;

2)G中度数为1的点不超过两个。

考虑到简单连通图中边的数目m不超过n,

1)若 m = n - 1,则可从任一度数为1的点搜索即可;

2)若 m = n,多余的一条边连接哈密顿路径上的两点,从任一度数为1的点搜索即可。

3)若不存在度数为1的点,从任一点开始搜索。

复杂度O(n)。

http://acm.hdu.edu.cn/showproblem.php?pid=5424

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 1e3 + 10;

struct Edge{
int to, next;
}edge[2 * maxn];

int n, d1, d0, N, S;
bool vis[maxn], ans;
int d[maxn], head[maxn];

void addEdge(int u, int v){
edge
.next = head[u];
edge
.to = v;
head[u] = N++;
}

bool inMap(int u, int v){
for(int i = head[u]; i + 1; i = edge[i].next){
int v1 = edge[i].to;
if(v1 == v) return 1;
}
return 0;
}

bool dfs(int u, int cnt){
if(cnt == n) return ans = 1;
if(ans) return 1;
for(int i = head[u]; i + 1; i = edge[i].next){
int v = edge[i].to;
if(vis[v]) continue;
vis[v] = 1;
dfs(v, cnt + 1);
vis[v] = 0;
}
}

int main(){
while(~scanf("%d", &n)){
memset(d, 0, sizeof d);
memset(head, -1, sizeof head);
N = 0;
for(int i = 0, u, v; i < n; i++){
scanf("%d%d", &u, &v);
if(u != v && !inMap(u, v)){
addEdge(u, v);
addEdge(v, u);
++d[u], ++d[v];
}
}
d0 = d1 = 0;
S = 1;
for(int i = 1; i <= n; i++){
if(!d[i]) ++d0;
else if(d[i] == 1){
++d1;
S = i;
}
}
if(d0 + d1 > 2){
puts("NO");
continue;
}
ans = 0;
memset(vis, 0, sizeof vis);
vis[S] = 1;
dfs(S, 1);
puts(ans ? "YES" : "NO");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: