您的位置:首页 > 其它

PAT (Advanced) 1034. Head of a Gang (30)

2018-03-03 12:52 489 查看
原题:1034. Head of a Gang (30)

解题思路:
这个题有一系列任务:1)找出所有连通分量的结点数及其总权重; 2)找出所有结点数大于2的连通分量中权重最大的点;3)将符合条件的最终结果按字典序排列输出。
有了以上目标,那么就可以想到用DFS找连通分量,但是在遍历时要注意无向图的处理(具体看daim),在遍历同时保存最大成员数以及连通分量的总权重即可。

代码如下:#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<string>
#include<vector>
using namespace std;
const int maxn = 1000 + 5;
vector<int> G[maxn*2];
vector<string> name;
map<string, int> IDcache;

int ID(string s)
{
if(IDcache.count(s)) return IDcache[s];
name.push_back(s);
return IDcache[s] = name.size()-1;
}

struct Edge
{
int from, to, w;
Edge(int u, int v, int w):from(u), to(v), w(w) {}
};

vector<Edge> edges;
vector<int> ans;
int n, threshold;
int vis[maxn*2], weight[maxn*2];
int num[maxn*2];

void dfs(int s, int& cnt, int& thres) //cnt表示结点个数, thres表示总权重
{
vis[s] = 1;
cnt++;
for(int i = 0; i < G[s].size(); i++)
{
Edge& e = edges[G[s][i]];
thres += e.w;
edges[G[s][i]^1].w = e.w = 0;// 异或表示取这条边的反向边,把访问过的边的权重清0,
//防止重复运算
if(!vis[e.to]) dfs(e.to, cnt, thres);
}
}

bool cmp1(int a, int b)
{
return weight[a] > weight[b];
}
bool cmp2(int a, int b)
{
return name[a] < name[b];
}
int main()
{
while(cin >> n >> threshold)
{
memset(weight, 0, sizeof(weight));
memset(vis, 0, sizeof(vis));
for(int i = 0; i < 2*n; i++) G[i].clear();
name.clear();
IDcache.clear();
for(int i = 0; i < n; i++)
{
string s1, s2;
int w;
cin >> s1 >> s2 >> w; //注意为无向图
edges.push_back(Edge(ID(s1), ID(s2), w));
edges.push_back(Edge(ID(s2), ID(s1), w));
G[ID(s1)].push_back(edges.size()-2);
G[ID(s2)].push_back(edges.size()-1);
}
vector<int> tmp, ans;
for(int i = 0; i < edges.size(); i += 2)//计算每个点的权重
{
weight[edges[i].from] += edges[i].w;
weight[edges[i].to] += edges[i].w;
}
for(int i = 0; i < name.size(); i++) tmp.push_back(i);
sort(tmp.begin(), tmp.end(), cmp1); //对所有结点按权重排序
for(int i = 0; i < tmp.size(); i++)
{
if(!vis[tmp[i]])
{
int cnt = 0, thres = 0;
dfs(tmp[i], cnt, thres);
num[tmp[i]] = cnt;
if(cnt > 2 && thres > threshold) ans.push_back(tmp[i]); //符合条件,加入最终结果
}
}
sort(ans.begin(), ans.end(), cmp2); //按字典序排序

96c9
cout << ans.size() << endl;
for(int i = 0; i < ans.size(); i++)
cout << name[ans[i]] << " " << num[ans[i]] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: