图的遍历 | 1034 map处理输入数据,连通块判断

Posted TQCAI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的遍历 | 1034 map处理输入数据,连通块判断相关的知识,希望对你有一定的参考价值。

这题写得比较痛苦。首先有点不在状态,其次题目比较难读懂。

“Gang”成立的两个条件:①成员数大于两个  ②边权总和大于阈值K

 

首先,在录数据的时候通过map或者字符串哈希建立string到int的映射。

然后,这个题的数据结构其实是带权无向图。在录数据的时候就要处理好点权边权

最后,对所有顶点做一遍dfs,汇总边权,找出最大点权和最大点权所在的点,把数据录进ans里。

 

注意的点一个是环路边权的汇总。方法是在dfs中通过先加边权判断vis是否遍历过。此时又要注意用不搜前驱点的dfs结果,及dfs(p,s) //p是前驱点,s是当前点

还有一个是邻接数组要开大一点。虽然给出的图的边数是小于1000,但是顶点数不一定。

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>

#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 0x06FFFFFF
#define V vector<int>

using namespace std;

string ID2name[LEN];
map<string,int> name2ID;
int g[LEN][LEN];
int nID=1;
int w[LEN];
int vis[LEN];
int cnt;
int maxV;
int maxID;
int gang[LEN];
int sum;
set<string> ans;

int getID(string s){
    int id=name2ID[s]; 
    if(id){
        return id;
    }else{
        name2ID[s]=nID;
        ID2name[nID]=s;
        return nID++;
    }
}

void dfs(int p,int s){
    vis[s]=1;
    cnt++;
    if(w[s]>maxV){
        maxV=w[s];
        maxID=s;
    }
    for(int i=1;i<nID;i++) if(g[s][i]>0 && i!=p){
        sum+=g[s][i];
        if(vis[i]) continue;
        dfs(s,i);
    }
}

int main(){
//    freopen("D:\\CbWorkspace\\PAT\\图的遍历\\1034_2.txt","r",stdin);
    int n,k,i,j;
    I("%d%d",&n,&k);
    FF(i,n){
        char buf[100];
        I("%s",buf);
        string a(buf);
        I("%s",buf);
        string b(buf);
        I("%d",&j);
        int ai=getID(a);
        int bi=getID(b);
        g[ai][bi]+=j;
        g[bi][ai]+=j;
        w[ai]+=j;
        w[bi]+=j;
    }
    F(i,1,nID+1) if(!vis[i]){
        cnt=0;
        maxV=-1;
        sum=0;
        dfs(-1,i);        //深搜 
        if(cnt>2 && sum>k){
            ans.insert(ID2name[maxID]);
            gang[maxID]=cnt;
        }
    }
    printf("%d\n",ans.size());
    set<string>::iterator it=ans.begin();
    while(it!=ans.end()){
        printf("%s %d\n",it->c_str(),gang[name2ID[*it]]);
        it++;
    }
    return 0;
}

 

以上是关于图的遍历 | 1034 map处理输入数据,连通块判断的主要内容,如果未能解决你的问题,请参考以下文章

树和图的深度优先遍历

PAT 甲级 1034 Head of a Gang (30 分)(bfs,map,强连通)

NC52275 图的遍历

PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]

图的最小生成树——Kruskal算法

以邻接多重表为存储结构,实现连通无向图的深度优先遍历和广度优先遍历。