1 10 1 1 9 1 8 8 10 10 3 8 6 1 2 10 4 9 5 3 7
-1 1 10 10 9 8 3 1 1 8
前两天刚学过图论中的最短路,今天做这道题,首先想到了用最短路的思想做。写了一个Bellman-Ford,超时了,原因是顶点数*边数太大。然后用广搜写了一下,AC。存储边时用了vector,记得每次都要清空vector。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
const int N = 100010;
int pre[N], vis[N], n, s;
vector<int> vec[N];
void Init()
{
for(int i = 1; i <= n; i++)
pre[i] = i, vis[i] = 0;
pre[s] = -1;
}
void bfs()
{
queue<int> Q;
Q.push(s);
while(!Q.empty())
{
int t = Q.front();
Q.pop();
if(vis[t])
continue;
vis[t] = 1;
for(int i = 0; i < vec[t].size(); i++)
{
int p = vec[t][i];
if(!vis[p])
{
pre[p] = t;
Q.push(p);
}
}
}
}
int main()
{
int t, i;
scanf("%d",&t);
while(t--)
{
memset(vec, 0, sizeof(vec));
scanf("%d%d",&n,&s);
int a, b;
for(i = 0; i < n - 1; i++)
{
scanf("%d%d",&a,&b);
vec[a].push_back(b);
vec[b].push_back(a);
}
Init();
bfs();
printf("%d",pre[1]);
for(i = 2; i <= n; i++)
printf(" %d",pre[i]);
printf("\n");
}
return 0;
}/*无根树转有根树,s即为根*/
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
const int N = 100010;
int pre[N], n, s;
vector<int> vec[N];
void Init()
{
for(int i = 1; i <= n; i++)
pre[i] = i;
pre[s] = -1;
}
void dfs(int u, int fa)
{
int k = vec[u].size();
for(int i = 0; i < k; i++)
{
int v = vec[u][i];
if(v != fa)
{
pre[v] = u;
dfs(v, u);
}
}
}
int main()
{
int t, i;
scanf("%d",&t);
while(t--)
{
memset(vec, 0, sizeof(vec));
scanf("%d%d",&n,&s);
int a, b;
for(i = 0; i < n - 1; i++)
{
scanf("%d%d",&a,&b);
vec[a].push_back(b);
vec[b].push_back(a);
}
Init();
dfs(s,-1); //从根节点开始搜
printf("%d",pre[1]);
for(i = 2; i <= n; i++)
printf(" %d",pre[i]);
printf("\n");
}
return 0;
}原文:http://blog.csdn.net/lyhvoyage/article/details/19421387