【C】图的遍历

1013. Battle Over Cities (25)

时间限制 400 ms

内存限制 65536 kB

代码长度限制 16000 B

判题程序
Standard 作者 CHEN, Yue

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.

For example, if we have 3 cities and 2 highways connecting city1-city2 and city1-city3. Then if city1 is occupied by the enemy, we must have 1 highway repaired, that is the highway city2-city3.

Input

Each input file contains one test case. Each case starts with a line containing 3 numbers N (<1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then M lines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.

Output

For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.

Sample Input

3 2 3
1 2
1 3
1 2 3

Sample Output

1
0
0

#include<stdio.h>
#include<iostream>
using namespace std;
const int maxn=1010;
//当在栈上申请大于1M是会出现栈溢出
//这里申请的内存过大,在vs08中栈溢出,但是在pat网站中可以通过
int G[maxn][maxn]={0};
int n,m,k;
void dfs(int u,int visited[]){
	visited[u]=1;
	int i;
	for(i=1;i<=n;i++){
		if(G[u][i]!=0){
			if(visited[i]==0) dfs(i,visited);
		}
	}
}//注意城市编号是1-n
void dfstrave(int &num,int toc){
	int i;
	int visited[maxn]={0};
	visited[toc]=1;//设置该城市已访问,下文不再访问
	for(i=1;i<=n;i++){
		if(visited[i]==0){
			dfs(i,visited);
			num++;//有num个城市群
		}
	}
}
int main(){
	cin>>n>>m>>k;
	int i,j,l;
	int tocheck[maxn];
	for(i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		G[a][b]=1;
		G[b][a]=1;
	}
	for(i=0;i<k;i++){
		cin>>tocheck[i];
	}
	for(i=0;i<k;i++){
		int G1[maxn][maxn]={0};
		for(j=1;j<=n;j++){
			for(l=1;l<=n;l++){
				G1[j][l]=G[j][l];
			}
		}
		for(j=1;j<=n;j++){
			G1[j][tocheck[i]]=0;
			G1[tocheck[i]][j]=0;
		}
		int num=0;
		dfstrave(num,tocheck[i]);
		cout<<num-1<<endl;
	}
	return 0;
}

1021. Deepest Root (25)

时间限制 1500 ms

内存限制 65536 kB

代码长度限制 16000 B

判题程序
Standard 作者 CHEN, Yue

A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes’ numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print “Error: K components” where K is the number of connected components in the graph.

Sample Input 1:

5
1 2
1 3
1 4
2 5

Sample Output 1:

3
4
5

Sample Input 2:

5
1 3
1 4
2 5
3 4

Sample Output 2:

Error: 2 components
#include<vector>
#include<set>
#include<iostream>
#include<stdio.h>
using namespace std;
const int maxn=10010;
vector<int> Adj[maxn];
set<int> Deepest1,Deepest2;//自动排序
int n,deepmax1=-1,deepmax2=-1;
void dfs(int start,int vis[]){//判断能否一次遍历完,即判断是否是一棵树
	int i;
	vis[start]=1;
	for(i=0;i<Adj[start].size();i++){
		if(vis[Adj[start][i]]==0) dfs(Adj[start][i],vis);
	}
}
int dfstrave(){
	int vis[maxn]={0};
	int i,num=0;
	for(i=1;i<=n;i++){
		if(vis[i]==0){
			dfs(i,vis);num++;
		}
	}
	return num;
}
void dfs1(int start,int vis[],int deep,int flag){
	int i;
	vis[start]=1;
	if(flag==1){//第一轮遍历
		if(deep>deepmax1){
			deepmax1=deep;
			//cout<<"start:"<<start<<"deep:"<<deep<<endl;
			Deepest1.clear();
			Deepest1.insert(start);
		}
		else if(deep==deepmax1){
			Deepest1.insert(start);
		}
		for(i=0;i<Adj[start].size();i++){
			if(vis[Adj[start][i]]==0){
				dfs1(Adj[start][i],vis,deep+1,1);
			}
		}
	}
	else{
		if(deep>deepmax2){
			deepmax2=deep;
			//cout<<"start:"<<start<<"deep:"<<deep<<endl;
			Deepest2.clear();
			Deepest2.insert(start);
		}
		else if(deep==deepmax2){
			Deepest2.insert(start);
		}
		for(i=0;i<Adj[start].size();i++){
			if(vis[Adj[start][i]]==0){
				dfs1(Adj[start][i],vis,deep+1,2);
			}
		}
	}
}
void dfstrave1(int start,int flag){
	int i;
	int vis[maxn]={0};
	for(i=start;i<=n;i++){
		if(vis[i]==0) dfs1(i,vis,0,flag);
	}
}
int main(){
	cin>>n;
	int i;
	for(i=1;i<n;i++){//注意,n个节点,n-1条线
		int a,b;
		cin>>a>>b;
		Adj[a].push_back(b);
		Adj[b].push_back(a);
	}
	int num=dfstrave();
	if(num!=1){
		cout<<"Error: "<<num<<" components"<<endl;
		return 0;
	}
	/*for(i=1;i<=n;i++) dfstrave1(i);*///遍历以每个顶点为起点,会超时
	dfstrave1(1,1);//先以任意顶点为起点,遍历,获得可以到达的最深节点集合Deepest
	set<int>::iterator it;
	it=Deepest1.begin();
	dfstrave1(*it,2);//第二轮遍历
	for(it=Deepest2.begin();it!=Deepest2.end();it++){
		Deepest1.insert(*it);
	}
	for(it=Deepest1.begin();it!=Deepest1.end();it++){
		printf("%d\n",*it);
	}
	return 0;
}

1034. Head of a Gang (30)

时间限制 100 ms

内存限制 65536 kB

代码长度限制 16000 B

判题程序
Standard 作者 CHEN, Yue

One way that the police finds the head of a gang is to check people’s phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls made between the two persons. A “Gang” is a cluster of more than 2 persons who are related to each other with total relation weight being greater than a given threshold K. In each gang, the one with maximum total weight is the head. Now given a list of phone calls, you are supposed to find the gangs and the heads.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers N and K (both less than or equal to 1000), the number of phone calls and the weight threshold, respectively. Then N lines follow, each in the following format:

Name1 Name2 Time

where Name1 and Name2 are the names of people at the two ends of the call, and Time is the length of the call. A name is a string of three capital letters chosen from A-Z. A time length is a positive integer which is no more than 1000 minutes.

Output Specification:

For each test case, first print in a line the total number of gangs. Then for each gang, print in a line the name of the head and the total number of the members. It is guaranteed that the head is unique for each gang. The output must be sorted according to the alphabetical order of the names of the heads.

Sample Input 1:

8 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Sample Output 1:

2
AAA 3
GGG 3

Sample Input 2:

8 70
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Sample Output 2:

0
#include<iostream>
#include<map>
#include<string>
using namespace std;
const int maxn=2010;
const int INF=1000000000;
map<string,int> stringtoint;//姓名->编号
map<int,string> inttostring;//编号->姓名
map<string,int> gang;//head->人数
int G[maxn][maxn]={0};//邻接矩阵
int w[maxn]={0};//点权
int n,k,numperson=0;//边数、访问下限、总人数
bool vis[maxn]={false};
void dfs(int nowvisit,int &head,int &nummember,int &totalvalue){
	//当前访问、头目、成员编号、总边权
	nummember++;
	vis[nowvisit]=true;
	if(w[nowvisit]>w[head]) head=nowvisit;
	for(int i=0;i<numperson;i++){
		if(G[nowvisit][i]>0){
			totalvalue+=G[nowvisit][i];//更新总边权
			G[nowvisit][i]=G[i][nowvisit]=0;//以后不再添加
			if(vis[i]==false){
				dfs(i,head,nummember,totalvalue);
			}
		}
	}
}
void dfstrave(){
	for(int i=0;i<numperson;i++){
		if(vis[i]==false){
			int head=i,nummember=0,totalvalue=0;
			dfs(i,head,nummember,totalvalue);
			if(nummember>2&&totalvalue>k){
				gang[inttostring[head]]=nummember;
			}
		}
	}
}
int change(string str){
	if(stringtoint.find(str)!=stringtoint.end()){
		return stringtoint[str];
	}
	else{
		stringtoint[str]=numperson;//编号
		inttostring[numperson]=str;
		return numperson++;
	}
}
int main(){
	cin>>n>>k;
	string str1,str2;
	int i,weight;
	for(i=0;i<n;i++){
		cin>>str1>>str2>>weight;
		int id1=change(str1);
		int id2=change(str2);
		w[id1]+=weight;
		w[id2]+=weight;
		G[id1][id2]+=weight;
		G[id2][id1]+=weight;
	}
	dfstrave();
	cout<<gang.size()<<endl;
	map<string,int>::iterator it;
	for(it=gang.begin();it!=gang.end();it++){
		cout<<it->first<<" "<<it->second<<endl;
	}
	return 0;
}

1076. Forwards on Weibo (30)

时间限制 3000 ms

内存限制 65536 kB

代码长度限制 16000 B

判题程序
Standard 作者 CHEN, Yue

Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may follow many other users as well. Hence a social network is formed with followers relations. When a user makes a post on Weibo, all his/her followers can view and forward his/her post, which can then be forwarded again by their followers. Now given a social network, you are supposed to calculate the maximum potential amount of forwards for any specific user, assuming that only L levels of indirect followers are counted.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=1000), the number of users; and L (<=6), the number of levels of indirect followers that are counted. Hence it is assumed that all the users are numbered from 1 to N. Then N lines follow, each in the format:

M[i] user_list[i]

where M[i] (<=100) is the total number of people that user[i] follows; and user_list[i] is a list of the M[i] users that are followed by user[i]. It is guaranteed that no one can follow oneself. All the numbers are separated by a space.

Then finally a positive K is given, followed by K UserID‘s for query.

Output Specification:

For each UserID, you are supposed to print in one line the maximum potential amount of forwards this user can triger, assuming that everyone who can view the initial post will forward it once, and that only L levels of indirect followers are counted.

Sample Input:

7 3
3 2 3 4
0
2 5 6
2 3 1
2 3 4
1 4
1 5
2 2 6

Sample Output:

4
5
#include<iostream>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
const int maxn=1010;
struct node{
	int data;
	int layer;
};
vector<node> Adj[maxn];
bool vis[maxn]={false};
int bfs(int s,int L){
	int numforward=0;//转发数
	queue<node> q;
	node start;
	start.data=s;
	start.layer=0;
	q.push(start);
	vis[start.data]=true;
	while(!q.empty()){
		node topnode=q.front();
		q.pop();
		int u=topnode.data;
		for(int i=0;i<Adj[u].size();i++){
			node next=Adj[u][i];
			next.layer=topnode.layer+1;
			if(vis[next.data]==false&&next.layer<=L){
				q.push(next);
				vis[next.data]=true;
				numforward++;
			}
		}
	}
	return numforward;
}
int main(){
	node user;
	int n,l,numfollow,idfollow;
	cin>>n>>l;
	for(int i=1;i<=n;i++){
		user.data=i;
		cin>>numfollow;
		for(int j=1;j<=numfollow;j++){
			cin>>idfollow;
			Adj[idfollow].push_back(user);//idfollow->user
		}
	}
	int numquery,s;
	cin>>numquery;
	for(int i=0;i<numquery;i++){
		memset(vis,false,sizeof(vis));
		cin>>s;
		int numforward=bfs(s,l);
		cout<<numforward<<endl;
	}
	return 0;
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/Li_Jiaqian/article/details/79429355
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞