这个题就别让题目唬住了,他就是想让你求图的相邻两个联通点是不是有一样的数字标志,就是所谓的颜色(他用不同的数字来区分)只要写出图来,用一个数组给每个点写上数字,遍历所有出现的边,看颜色(数字)是否相同即可;
#include <bits/stdc++.h>
using namespace std;
const int manx=1e6+10;
int V,E,K;
int OS;
set<int>wuhu;
int b[600];
struct yyh
{
int a;
int b;
} a[manx];
int main()
{
scanf("%d %d %d",&V,&E,&K);
for(int i=1; i<=E; i++)
{
scanf("%d %d",&a[i].a,&a[i].b);
}
int l;
scanf("%d",&l);
for(int i=1; i<=l; i++)
{
memset(b,0,sizeof(b));
wuhu.clear();
for(int j=1; j<=V; j++)
{
scanf("%d",&OS);
b[j]=OS;
wuhu.insert(OS);
}
if(wuhu.size()==K)
{
int flag=0;
for(int j=1; j<=E; j++)
{
if(b[a[j].a]==b[a[j].b])
{
printf("No\n");
flag=1;
break;
}
}
if(flag==0)
{
printf("Yes\n");
}
}
else
{
printf("No\n");
}
}
return 0;
}
这个题是和连通分量有关的题目,连通分量变大就说明他的连通性变了。用DFS做。
#include <bits/stdc++.h>
using namespace std;
bool visit[510];
int e[510][510], n, m, k;
void dfs(int node)
{
visit[node] = true;
for( int i = 0; i < n; i++)
{
if( visit[i] == false && e[node][i] == 1)
dfs(i);
}
}
int countcnt()
{
int cnt = 0;
fill( visit, visit + 510, false );
for( int i = 0; i < n; i++)
{
if( visit[i] == false)
{
dfs(i);
cnt++;
}
}
return cnt;
}
int main()
{
scanf("%d%d", &n, &m);
int a, b, city;
for( int i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
e[a][b] = e[b][a] = 1;
}
int cnt = countcnt();
scanf("%d", &k);
for( int i = 0; i < k; i++)
{
scanf("%d", &city);
for( int j = 0; j < n; j++)
{
if( e[city][j] == 1)
{
e[city][j] = 0;
e[j][city] = 0;
}
}
int tempcnt = countcnt();
if( tempcnt > cnt + 1)
printf("Red Alert: City %d is lost!\n", city);
else
printf("City %d is lost.\n", city);
cnt = tempcnt;
if( i == n - 1)
printf("Game Over.\n");
}
return 0;
}
题目:功夫传人DFS+BFS
#include <bits/stdc++.h>
using namespace std;
const int manx=1e5+10;
int n;
double z,r;
double sum=0;
vector<int> s[manx];
int arr[manx]= {0};
int k;
void dfs(int num,double zz)
{
if(!s[num].size())
{
sum+=zz*arr[num];
}
else
{
for(int i=0; i<s[num].size(); i++)
{
dfs(s[num][i],zz*(1-r/100));
}
}
}
int main()
{
scanf("%d %lf %lf",&n,&z,&r);
for(int i=0; i<n; i++)
{
scanf("%d",&k);
if(k==0)
{
scanf("%d",&arr[i]);
}
else
{
for(int j=1; j<=k; j++)
{
int w;
scanf("%d",&w);
s[i].push_back(w);
}
}
}
dfs(0,z);
printf("%.lld",(long long)sum);
//这里用printf("%.0lf",sum);有一个样例不过,原因是%.xlf是默认四舍五入的.
//而第一种写法直接去掉了小数部分,是向下取整的。
return 0;
}
列出连通集,BFS的while队列循环里面一定要先更新num从传到子函数里的值变成队列第一个数的值,不然会错!
#include <bits/stdc++.h>
using namespace std;
int n,E;
int e[15][15];
int v[15];
void DFS(int num)
{
v[num]=1;
printf("%d ",num);
for(int i=0; i<n; i++)
{
if(e[num][i]!=0&&v[i]==0)
{
DFS(i);
}
}
}
void BFS(int num)
{
queue<int>que;
v[num]=1;
que.push(num);
while(que.size())
{
num=que.front();//一定要更新num的值
printf("%d ",num);
que.pop();
for(int i=0;i<n;i++)
{
if(e[num][i]!=0&&v[i]==0)
{
v[i]=1;
que.push(i);
}
}
}
}
int main()
{
scanf("%d %d",&n,&E);
int x,y;
for(int i=1; i<=E; i++)
{
scanf("%d %d",&x,&y);
e[x][y]=e[y][x]=1;
}
for(int i=0; i<n; i++)
{
if(v[i]==0)
{
printf("{ ");
DFS(i);
printf("}\n");
}
}
fill(v,v+15,0);
for(int i=0;i<n;i++)
{
if(v[i]==0)
{
printf("{ ");
BFS(i);
printf("}\n");
}
}
return 0;
}
题目:地下迷宫搜索
#include <bits/stdc++.h>
using namespace std;
int e[1010][1010];
int n,m,s;
int sum=0;//标记自己走了几个路口,如果全遍历了,sum==n,否则需要多输出个0
int vis[1010];
int f=0;//就为了格式问题,在非第一次输出的前面打个空格
void dfs(int s)
{
if(f!=0)
{
printf(" ");
}
f++;
printf("%d",s);
for(int i=1;i<=n;i++)
{
if(vis[i]==0&&e[s][i]!=0)
{
vis[i]=1;
sum++;
dfs(i);
printf(" %d",s);//如何原路返回的方式
}
}
}
int main()
{
int q,w;
scanf("%d %d %d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
scanf("%d %d",&q,&w);
e[w][q]=e[q][w]=1;
}
vis[s]=1;
sum++;
dfs(s);
if(sum<n)
{
printf(" 0");
}
return 0;
}