Bacon Number 两种解法

View Code
/*
【题目来源】
http://soj.me/show_problem.php?pid=1004&cid=567

【题目分析】 
与longth way 类似 
这个好象就是传说中的六度人脉,你只要通过六度人脉就可以找到世界上的任何一个人。
假设一个人一生会认识N个人,那N+N^1+N^2+N^3+N^4+N^5+N^6>=世界总人数。
给定一些边确定一个图,即给定一些点之间的连通情况,求出各点到0的最短路径 

【思路分析】 
1.邻接表构图 
2.以0为树根,层次遍历,求出其他各点的深度 即为所求 

【小小心得】 
刚开始还去用struct表示Node
其实只用一个邻接表就行了 邻接表果然好东西呀~ 
*/
#include <iostream>
#include <vector>
#include <queue> 
using namespace std; 

#define Max 101

int main()
{
    int m;
    
    cin >> m;
    
    while (m--)
    {   
        int n;
        
        cin >> n;
        
        vector<int> v[Max];
        
        //建表 
        int temp1, temp2;
        for (int i = 0; i < n; ++i)
        {
            cin >> temp1 >> temp2;
            
            v[temp1].push_back(temp2);
            
            v[temp2].push_back(temp1);
        }
        
        int layer[Max] = {0};//深度 
        
        bool visit[Max] = {0};//是否被访问过 
        
        queue<int> q;
        
        q.push(0);
        
        while (!q.empty())
        {
            int current = q.front();
            
            q.pop();
            
            for (int i = 0; i < v[current].size(); ++i)
            {
                if (!visit[v[current][i]])
                {
                    layer[v[current][i]] = layer[current]+1;//深度相对+1
                    
                    visit[v[current][i]] = 1;//已访问 
                    
                    q.push(v[current][i]);
                }
            }
        }
        
        for (int i = 1; i < Max; ++i)
            if (layer[i]) cout << i << ":" << layer[i] << endl;
        
        cout << "---" << endl;
    }
}
View Code
/*
受RY提示,此题有一种比较容易敲出来的算法,于是考试的时候就用了这种哈哈。 
第二种思路:Floyd-Warshall算法(它真的叫猥琐算法吗??)

Floyd-Warshall算法是解决任意两点间的最短路径的一种算法。
通常可以在任何图中使用,包括有向图、带负权边的图。

复杂度比BFS的要高 O(n^3)
思路很容易,3个循环寻找任意两点间的最小值。 

【小小心得】 
除非是对数组清零,否则不要轻易用memset. 

*/

#include <iostream>
using namespace std;

#define Max 101

int s[Max][Max];

int main()
{
    int m;
    
    cin >> m;
    
    while (m--)
    {
        int n;
        
        cin >> n;
        
        //记住,除非是对数组清零,否则不要轻易用memset. 
        for (int i = 0; i < Max; ++i)
            for (int j = 0; j < Max; ++j)
                s[i][j] = 999999;
        
        //输入,无向图,同时更新2个地方 
        int temp1, temp2;
        for (int i = 0; i < n; ++i)
        {
            cin >> temp1 >> temp2;
    
            s[temp1][temp2] = 1;
            
            s[temp2][temp1] = 1;
        }
        
        //Floyd-Warshall算法特征: 3个循环 
        for (int k = 0; k < Max; ++k)
        {
            for (int i = 0; i < Max; ++i)
            {
                for (int j = 0; j < Max; ++j)
                {
                    if (s[i][k] + s[j][k] < s[i][j])
                    {
                        s[i][j] = s[i][k]+s[j][k];
                        
                        s[j][i] = s[i][j];
                    }
                }
            }
        }
        
        //输出其他各点到0的距离 
        for (int i = 1; i < Max; ++i)
        {
            if (s[0][i] != 999999)
                cout << i << ':' << s[0][i] << endl;
        }
        
        cout << "---" << endl;
    }
}

 

posted @ 2012-12-15 16:20  Norcy  阅读(1021)  评论(0编辑  收藏  举报