NYOJ 20 吝啬的国度 【BFS+链式前向星建图,Vector建图】

吝啬的国度

时间限制:1000 ms  |  内存限制:65535 KB

难度:3

描述
在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来。现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路)。

输入
第一行输入一个整数M表示测试数据共有M(1<=M<=5)组

每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<=S<=100000),N表示城市的总个数,S表示参观者所在城市的编号

随后的N-1行,每行有两个正整数a,b(1<=a,b<=N),表示第a号城市和第b号城市之间有一条路连通。

输出
每组测试数据输N个正整数,其中,第i个数表示从S走到i号城市,必须要经过的上一个城市的编号。(其中i=S时,请输出-1)
样例输入
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
来源
经典题目
上传者
张云聪

原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=20

如果采用邻接矩阵建图,你懂的,进而想到链式前向星建图+BFS解决,当然用DFS也行。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=100000+5;
int n,s;
struct Edge
{
    int u,v,next;
} edge[maxn<<1];
int head[maxn];
int cnt;
bool vis[maxn];
int pre[maxn];
void Init()
{
    cnt=0;
    for(int i=1; i<=n; i++)
    {
        vis[i]=false;
        head[i]=-1;
        pre[i]=-1;
    }
}
void addEdge(int u,int v)
{
    edge[cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void BFS()
{
    vis[s]=true;
    pre[s]=-1;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int p=q.front();
        q.pop();
        for(int i=head[p]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(!vis[v])
            {
                vis[v]=true;
                pre[v]=p;
                q.push(v);
            }
        }
    }
}
int main()
{
    int T;
    //freopen("data/20.txt","r",stdin);
    cin>>T;
    while(T--)
    {
        cin>>n>>s;
        int x,y;
        Init();
        for(int i=1; i<n; i++)
        {
            scanf("%d%d",&x,&y);
            addEdge(x,y);
            addEdge(y,x);
        }
        /**
        for(int i=1; i<=n; i++)
        {
            cout<<i<<":";
            for(int j=head[i]; ~j; j=edge[j].next)
            {
                cout<<edge[j].v<<" ";
            }
            cout<<endl;
        }
        */
        BFS();
        for(int i=1; i<=n; i++)
        {

            if(i!=1)
                printf(" ");
            printf("%d",pre[i]);
        }
        cout<<endl;
    }
    return 0;
}

网上别人代码:Vector建图+BFS

讨论区92楼   xiangfeng林少

#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
vector<int>a[100005];
int b[100005],n,s;
void dfs(int x,int y)
{
    for (int i = 0; i <a[x].size(); i++)
        if (a[x][i] != y)
            dfs(a[x][i],b[a[x][i]]=x);
    return;
}
int main()
{
    int M,x,y;
    scanf("%d",&M);
    while (M--)
    {
        scanf("%d%d",&n,&s);
        for (int i = 1; i <n; i++)
        {
            a[i].clear();
        }
        for (int i = 1; i <n; i++)
        {
            scanf("%d%d",&x,&y);
            a[x].push_back(y); //相当二维数组
            a[y].push_back(x);
        }
        b[s] = -1;//与S相等则为-1
        dfs(s,-1);
        for (int i = 1; i <= n; i++)
            printf("%d ",b[i]);
        printf("\n");
    }
    return 0;
}

OJ标程代码:


#include<iostream>
#include<vector>
#include<iterator>
using namespace std;
void MakeRoot(int search,int root,const vector<vector<int> >& g,vector<int> &result)
{
	for(vector<int>::const_iterator it=g[search].begin();it!=g[search].end();++it)
	{
		if(result[*it]==0)
		{
			result[*it]=search;
			MakeRoot(*it,root,g,result);
		}
	}
}
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		int m,a,b;
		cin>>m; int root;
		cin>>root; //m个点
		vector<vector<int> > g(m+1,vector<int>());
		for(int i=0;i!=m-1;i++)
		{
			cin>>a>>b;
			g[a].push_back(b);
			g[b].push_back(a);
		}
		vector<int> result(m+1);
		result[root]=-1;
		MakeRoot(root,root,g,result);
		copy(result.begin()+1,result.end(),ostream_iterator<int>(cout," "));
	}
}
        

本题目前排行第一代码

用户:李泉,运行号:1470045

#include <stdio.h>
#include <memory.h>  

int map[100005];  

void Adjust(int currentCity)
{
    int priorCity = map[currentCity];
    if (priorCity != 0)
    {
        Adjust(priorCity);
        map[priorCity] = currentCity;
    }
}  

int main()
{
    int i, testNum, cityNum, startCity, cityA, cityB;
    scanf("%d", &testNum);
    while (testNum-- != 0)
    {
        scanf("%d%d", &cityNum, &startCity);
        memset(map, 0, sizeof(int)*cityNum + 1);
        for (i = 1; i < cityNum; i++)
        {
            scanf("%d%d", &cityA, &cityB);
            if (map[cityB] == 0)
            {
                map[cityB] = cityA;
            }
            else
            {
                Adjust(cityA);
                map[cityA] = cityB;
            }
        }
        Adjust(startCity);
        map[startCity] = - 1;
        for (i = 1; i < cityNum; i++)
        {
            printf("%d ", map[i]);
        }
        printf("%d\n", map[i]);
    }
    return 0;
}          

转载请注明出处:http://blog.csdn.net/hurmishine

时间: 2024-12-22 18:41:19

NYOJ 20 吝啬的国度 【BFS+链式前向星建图,Vector建图】的相关文章

图的存储结构:邻接矩阵(邻接表)&amp;链式前向星

[概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组graph[ ][ ]来记录图中点a与点b之间是否连通,初始化为0(或者-1之类的看情况):如果图中有可忽略的重边(如 只需重边中的最小边或最大边),则保存需要的那条边的边权,但如果有无法忽略的重边,就一定不要用邻接矩阵. int graph[MAXN][MAXN]; void graphInit() { me

HDU1035 Robot Motion【链式前向星】

Robot Motion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7039    Accepted Submission(s): 3244 Problem Description A robot has been programmed to follow the instructions in its path. Instruc

图的存储:链式前向星(边集数组)

申明:本文中提及的所有存图结构都用静态数组实现,而非链表. 0.什么是链式前向星 链式前向星是一种存图的结构,例如前向星.邻接矩阵.边表.邻接表等也是存图的结构. 1.链式前向星有何优点 链式前向星:空间利用率高,在各类竞赛中常被使用. 邻接矩阵:需要开N*N的空间,在各类竞赛中常被卡. 邻接表:空间复杂度略小于邻接矩阵,但会被极端数据卡爆,且无法记录权值. 边表:无法迅速判断两点连通性,以至不适用于大多数图的算法. 前向星:具有排序操作,时间复杂度高. 2.同类结构介绍 邻接矩阵:开二维数组,

链式前向星BFS

采用链式前向星的BFS: #include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; typedef long long LL; const int maxN = 100 + 3;

链式前向星写法下的DFS和BFS

Input 5 7 1 2 2 3 3 4 1 3 4 1 1 5 4 5 output 1 5 3 4 2 #include<bits/stdc++.h> using namespace std; const int maxn = 150; const int maxm = 1050; int n, m;//顶点数,边数 int head[maxm], tot; bool used[maxn]; //head[u]表示已知的最后一条以u为起点的边在边集e中的下标 struct edge {

poj-1459-最大流dinic+链式前向星

title: poj-1459-最大流dinic+链式前向星 date: 2018-11-22 20:57:54 tags: acm 刷题 categories: ACM-网络流-最大流 概述 这道是一道网络流里最大流的板子题,,, 暑期集训网络流草草水过,,连基本的算法都不知道有哪些,,,更别提怎么实现了,,,只知道网络流的大致的概念,, 今天花了一天的时间重新学习了一波,,,本以为这东西很简单,,,没想到不仅算法的实现一大堆的东西,,就连题目都有时候看不懂,,,,感受就是网络流的题不仅算法实

关于MOD&amp;链式前向星-2015年9月25日

好久没写了,其实一直也在做,但是没心情写总结文章,所以还是以后做一点就写一点吧. 最近状态很差很差,打水题都过不了,我也是醉了. 重做了去年的两道noip题,D1T2和D2T3,里面包括了MOD运算. MOD运算基本满足四则运算,所以很多表达式在模p意义下都是等价的,但除法除外. 但是还要注意,需要在非负情况下进行计算,当出现减法时,一定要加到正值再做. 另外注意溢出的问题,及时取模也是很重要的. noip2014D1T2可以用链式前向星存图. 大概就是这样: struct Edge{ int

最短路 spfa 算法 &amp;&amp; 链式前向星存图

推荐博客  https://i.cnblogs.com/EditPosts.aspx?opt=1 http://blog.csdn.net/mcdonnell_douglas/article/details/54379641 spfa  自行百度 说的很详细 spfa 有很多实现的方法  dfs  队列  栈  都可以 时间复杂度也不稳定 不过一般情况下要比bellman快得多 #include <stdio.h> #include <math.h> #include <st

链式前向星-学习笔记

模板: 数据结构: int head[LEN]; //记录源点u在mp中第一个地址i=head[u] 调用完之后就可以用mp[i]访问边表mp int cnt=0; //边表下标,随着数据的录入而扩张 struct edge{ //边 int to,next,w; }; edge mp[LEN]; //边表 加边函数: void add(int u,int v,int w){ //增加边 mp[cnt].to=v; mp[cnt].w=w; mp[cnt].next=head[u]; //指向源