A1013
题意:
图的遍历法求联通块:
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=1001;
//这道题中,肯定是求连通块数,思考下,我觉得还是用邻接表来存放数据,然后DFS求其连通块数
vector<int> child[maxn]; //由于是没有边权,所以直接用vector二位数组即可
bool inq[maxn]={false};
int shanchu;
int n,m,k;
void DFS(int index)
{
if(index==shanchu) //因为DFS除了在main函数中调用外,在自身中还是有递归调用,而且在输入时设置的也是两个方向,所以如果当前访问的结点是删除的结点直接返回
return ;
inq[index]=true; //进行标记
for(int i=0; i<child[index].size(); i++) //for循环去标记其孩子
{
if(inq[child[index][i]]==false)
DFS(child[index][i]);
}
}
int main()
{
cin >> n >> m >> k;
int temp1,temp2;
for(int i=0; i<m; i++)
{
cin >> temp1 >> temp2;
child[temp1].push_back(temp2); //这道题是图,而且是无向图,所以设置两个方向
child[temp2].push_back(temp1);
}
for(int i=0; i<k; i++) //这个循环是按照题中所给的次数
{
int ans=0;
memset(inq,false,sizeof(inq));
cin >> shanchu;
for(int j=1; j<=n; j++) //这个循环是统计除了删除的点之外剩下的所有连通的块数
if(j!=shanchu && inq[j]==false)
{
DFS(j); //走进来一个值,通过深度优先搜索将和该点相连的所有点进行标记
ans++;
}
cout << ans-1 << endl; //所以添加的边数就是连通块数-1
}
}
A1021
用vector数组来存放数字,并查集求连通块数
#include<iostream>
#include<vector>
#include<set>
using namespace std;
const int maxn=10001;
int n,maxv=-1;
set<int> fac,temp;
vector<int> child[maxn];
bool inq[maxn]={false};
void DFS(int index)
{
inq[index]=true;
for(int i=0; i<child[index].size(); i++)
{
if(inq[child[index][i]]==false)
DFS(child[index][i]);
}
}
void DFS1(int index,int depth,int pre)
{
if(depth>maxv) //找出最大深度
{
maxv=depth;
temp.erase(temp.begin(),temp.end()); //如果遇到新的高度的值,需要清空set中的值
temp.insert(index);
}
else if(depth==maxv)
{
temp.insert(index);
}
for(int i=0; i<child[index].size(); i++)
{
if(child[index][i]==pre) //如果在当前的index下的孩子结点中发现和父亲结点相同的,则跳过
continue;
DFS1(child[index][i],depth+1,index);
}
}
int main()
{
cin >> n;
int temp1,temp2;
for(int i=0; i<n-1; i++)
{
cin >> temp1 >> temp2;
child[temp1].push_back(temp2);
child[temp2].push_back(temp1);
}
int ans=0;
for(int i=1; i<=n; i++)
{
if(inq[i]==false)
{
DFS(i);
ans++;
}
}
DFS(1);
if(ans!=1)
printf("Error: %d components",ans);
else
{
DFS1(1,1,-1);
for(set<int>::iterator it=temp.begin(); it!=temp.end(); it++)
{
fac.insert(*it);
}
DFS1(*fac.begin(),1,-1);
for(set<int>::iterator it=temp.begin(); it!=temp.end(); it++)
{
fac.insert(*it);
}
for(set<int>::iterator it=fac.begin(); it!=fac.end(); it++)
cout << *it << endl;
}
return 0;
}
A1034
1.根据输入求出weight数组如下
#include<iostream>
#include<map>
using namespace std;
const int maxn=2001;
int n,k,num=0;
int G[maxn][maxn]; //对于全局变量的数组而言,如果不设置初始值,其值默认为0
int weight[maxn];
bool inq[maxn]={false};
map<string,int> StringInt;
map<int,string> IntString;
map<string,int> Gang;
int str(string s)
{
if(StringInt.find(s)!=StringInt.end())
return StringInt[s];
else
{
StringInt[s]=num;
IntString[num]=s;
return num++;
}
}
//注意一个连通块中的人数,权值之和,头目
void DFS(int index,int &head,int &Nown,int &sum)
{
Nown++;
if(weight[index]>weight[head])
head=index;
inq[index]=true;
for(int i=0; i<num; i++) //因为不知道连通块有多大,所以还是遍历所有的点
{
if(G[index][i]!=0) //从当前结点index出发,如果路径不是0,意味着可以到大i,但是只要访问过该路径,就把这条路毁了
{
sum+=G[index][i]; //计算该连通块内的路径
G[index][i]=G[i][index]=0; //毁掉这条路
if(inq[i]==false) //如果当前这个点没有被访问过,则从该点出发,继续继续深入访问下去
DFS(i,head,Nown,sum);
}
}
}
void DFSTrave()
{
for(int i=0; i<num; i++) //遍历所有的人,当然是之前计算的num
{
if(inq[i]==false)
{
int head=i,Nown=0,sum=0;
DFS(i,head,Nown,sum);
if(Nown>2 && sum>k)
{
Gang[IntString[head]]=Nown;
}
}
}
}
int main()
{
cin >> n >> k;
string temp1,temp2;
int temp3;
for(int i=0; i<n; i++)
{
cin >> temp1 >> temp2 >> temp3;
int id1=str(temp1);
int id2=str(temp2);
G[id1][id2]+=temp3;
G[id2][id1]+=temp3;
weight[id1]+=temp3;
weight[id2]+=temp3;
}
DFSTrave();
cout << Gang.size() << endl;
for(map<string,int>::iterator it=Gang.begin(); it!=Gang.end(); it++)
cout << it->first << " " << it->second << endl;
return 0;
}
A1076
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=1001;
int n,l;
struct node
{
int v;
int layer;
};
vector<node> child[maxn];
bool inq[maxn]={false};
//这道题是广度优先搜索
int BFS(int temp)
{
node start;
start.v=temp;
start.layer=0;
queue<node> q;
q.push(start);
inq[temp]=true;
int ans=0;
while(!q.empty())
{
node top=q.front();
q.pop(); //弹出首结点
int u=top.v;
for(int i=0; i<child[u].size(); i++)
{
node next=child[u][i];
next.layer=top.layer+1;
if(inq[next.v]==false && next.layer<=l)
{
inq[next.v]=true; //如果之前没有访问过,那么在访问之后就标记访问过了
q.push(next);
ans++;
}
}
}
return ans;
}
int main()
{
cin >> n >> l;
int temp1,temp2;
for(int i=1; i<=n; i++)
{
cin >> temp1;
for(int j=0; j<temp1; j++)
{
node s; //设置一个结构的结点
cin >> temp2; //输入temp2
s.v=i;
child[temp2].push_back(s);
}
}
cin >> temp1;
for(int i=0; i<temp1; i++)
{
memset(inq,false,sizeof(inq));
cin >> temp2;
cout << BFS(temp2) << endl;
}
}