pat题目求解

SCRCLS 2012-10-22 05:55:57
1021. Deepest Root (25)

时间限制
1500 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue
A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes' numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components in the graph.

Sample Input 1:
5
1 2
1 3
1 4
2 5
Sample Output 1:
3
4
5
Sample Input 2:
5
1 3
1 4
2 5
3 4
Sample Output 2:
Error: 2 components




http://pat.zju.edu.cn/contests/pat-practise/1021
1021. Deepest Root (25)

pat的一个题目,前面的csae过不了,想不明白哪里出错,求指教,谢谢




#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node
{
int data;
struct node *next;
}Node, *Ver;//节点

typedef struct
{
int v, e;
Ver *s;//头结点数组
}Graph;//邻接表表示图

typedef struct
{
int num;
int data;
}Deep;

int visit[MAX];
Deep deep[MAX];

void Init(Graph *G)//初始化图
{
int i;
int s, e;
Node *temp;

scanf("%d", &G->v);

G->e = G->v - 1;
G->s = (Ver *)malloc(sizeof(Ver) * G->v);

for (i = 0; i < G->v; i++)
{
G->s[i] = (Node *)malloc(sizeof(Node));
G->s[i]->next = NULL;
G->s[i]->data = 0;
}

for (i = 0; i < G->e; i++)//无向图
{
scanf("%d%d", &s, &e);

s -= 1;
e -= 1;

temp = (Node *)malloc(sizeof(Node));
temp->data = e;
temp->next = G->s[s]->next;
G->s[s]->next = temp;

temp = (Node *)malloc(sizeof(Node));
temp->data = s;
temp->next = G->s[e]->next;
G->s[e]->next = temp;
}
}

int cmp(const void *a, const void *b)//快排的cmp
{
Deep *c = (Deep *)a;
Deep *d = (Deep *)b;

if (c->data != d->data)//按照高度降序
return d->data - c->data;
else //如果高度想同,那么按照序号升序
return c->num - d->num;
}

void Clear(int len)//清空visit
{
memset(visit, 0, sizeof(int) * (len + 1));
}

void DFS(Graph G, int start, int *high)//深度搜索
{
int v;
int flag = 0;
Node *temp;

visit[start] = 1;

temp = G.s[start]->next;
while (temp)
{
v = temp->data;
if (!visit[v])
{
if (flag == 0)
{
*high += 1;
flag = 1;//已到过该层
}
DFS(G, v, high);
}
temp = temp->next;
}
}

void DFSVisit(Graph G)
{
int i, j = 0;
int high = 1, count = 0;
int max;

Clear(G.v);

for (i = 0; i < G.v; i++)//判断是否强连通
if (!visit[i])
{
DFS(G, i, &high);
count++;
}
if (count > 1)
printf("Error: %d components\n", count);
else //强连通
{
for (i = 0; i < G.v; i++)//逐个找出每个节点的deepest tree high
{
Clear(G.v);
high = 1;
DFS(G, i, &high);
deep[j].num = i + 1;
deep[j++].data = high;
}
qsort(deep, j, sizeof(Deep), cmp);//排序

max = deep[0].data;

for (i = 0; i < j && deep[i].data == max; i++)//输出节点
{
printf("%d\n", deep[i].num);
}

}

}


int main()
{
Graph G;

Init(&G);
DFSVisit(G);
return 0;
}


...全文
249 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
SCRCLS 2012-10-27
  • 打赏
  • 举报
回复
没有去掉重复点是什么意思,我最后排序了,应该不会重复的吧,

深度搜索是错误的么??

谢谢
[Quote=引用 1 楼 的回复:]

我觉得应该是广度优先啊。
附上我的代码,你自己对着看。并查集+深度优先。
另外,你也没有去除重复的点

C/C++ code

#include <iostream>
#include <string>
#include <algorithm>
#include <memory.h>
#include <cstdio>
#include <cstdlib>
#i……
[/Quote]
cstur4 2012-10-27
  • 打赏
  • 举报
回复
是树的话深入应该没问题,但是重复点还是有可能的[Quote=引用 4 楼 的回复:]

没有去掉重复点是什么意思,我最后排序了,应该不会重复的吧,

深度搜索是错误的么??

谢谢
引用 1 楼 的回复:

我觉得应该是广度优先啊。
附上我的代码,你自己对着看。并查集+深度优先。
另外,你也没有去除重复的点

C/C++ code

#include <iostream>
#include <string>
#include <algorithm>
……
[/Quote]
cstur4 2012-10-23
  • 打赏
  • 举报
回复
我觉得应该是广度优先啊。
附上我的代码,你自己对着看。并查集+深度优先。
另外,你也没有去除重复的点


#include <iostream>
#include <string>
#include <algorithm>
#include <memory.h>
#include <cstdio>
#include <cstdlib>
#include <set>
#include <vector>
#include <queue>
using namespace std;
#define MAX 0Xfffffff
int dis[10001];
int n;
vector<int> map[10001];//邻接表
int father[10001];
int visit[10001];
vector<int> ans;
int getfather(int i){
if(i==father[i])
return i;
return father[i] = getfather(father[i]);
}
void unionmerge(int i, int j){
father[i] = j;
}
int bfs(int x){
queue<int> q;
memset(visit, 0, sizeof(visit));
visit[x] = 1;
int maxv = 0;
q.push(x);
while(!q.empty()){
int v = q.front();
q.pop();
if(dis[v]>maxv)
maxv = dis[v];
for(int i=0;i<map[v].size();++i)
if(!visit[map[v][i]]){
visit[map[v][i]] = 1;
dis[map[v][i]] = dis[v] + 1;
q.push(map[v][i]);
}
}
return maxv;

}
int main(){

//freopen("in.txt", "r", stdin);

int a, b;
cin>>n;
for(int i=1;i<=n;++i)
father[i] = i;
for(int i=0;i<n-1;++i){
scanf("%d%d", &a, &b);
map[a].push_back(b);
map[b].push_back(a);
unionmerge(getfather(a), getfather(b)); //getfather合并
}
set<int> ss;
for(int i=1;i<=n;++i){
int f = getfather(i);
if(ss.count(f)<=0){
ss.insert(f);
}
}
if(ss.size()!=1){
printf("Error: %d components\n", ss.size());
}else{

int maxv = bfs(1);
for(int i=1;i<=n;++i){
if(dis[i]==maxv)
ans.push_back(i);
}
maxv = bfs(ans[0]);
for(int i=1;i<=n;++i){
if(dis[i]==maxv)
ans.push_back(i);
}

sort(ans.begin(), ans.end());
printf("%d\n", ans[0]);
//去掉重复的
for(int i=1;i<ans.size();++i)
if(ans[i]!=ans[i-1])
printf("%d\n", ans[i]);
}

//fclose(stdin);
}




FancyMouse 2012-10-23
  • 打赏
  • 举报
回复
不连通的问题不存在。不连通的图本身就不是树了,输出Error。

树的最长路径其实有个很方便的求法。任取一个点x,求出距离x最远的一个点y,然后求出距离y最远的一个点z。y到z就是一条最长路径。
cfvmario 2012-10-23
  • 打赏
  • 举报
回复
求图中最长路径问题。
我想到的方法是:

建立元素为0、1(false,true)的邻接矩阵A表示边存在与否。令矩阵C1=A
使用布尔运算,计算A*A=B,C1|B=C2,C2即为路径长度不超过2的邻接矩阵。
再循环计算A*B=B, C2|B=C3,C3即为路径长度不超过3的邻接矩阵,等等……

直到C中所有元素都不为0,或Cn-1中仍有0元素(说明图不连通)为止。设Ck-1中有0元素,Ck没有了,则Ck-1中0元素的坐标(起点、终点)就是最深树的根。
==============================================
但是一看完问题,问题来了,如果图不连通,我这个方法能求到连通分量个数么?还要求这个,就坑爹了……

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧