最近做了几道相关题目,在这里分享一下:
1.
#include<iostream>
#include<cstring>
using namespace std;
int mm[1005][1005]; //记录是否有联系
int vis[1005];
int n,m,cnt=0;
int count[1005];
int ans=0;
int strat,e; //注意要写到全局变量里,被调用函数要用
void dfs(int u){
vis[u]=1;//标记
if(u==e){
ans++;//一共有多少条
for(int i=1;i<=n;i++){
//记录此条路径下,经过哪些点
if(vis[i])count[i]++;//是否为关键点
}
return;
}
for(int i=1;i<=n;i++){
if(mm[u][i]&&!vis[i])//如果相连并且没有访问
{
dfs(i);
vis[i]=0;//回溯,写在循环体里面
}
}
}
int main(){
cin>>n>>m;
int a,b;
//初始化
memset(mm,0,sizeof(mm));
memset(vis,0,sizeof(vis));
memset(count,0,sizeof(count));
while(m--){
cin>>a>>b;
mm[a][b]=mm[b][a]=1;
}
//起点,终点
cin>>strat>>e;
dfs(strat);
for(int i=1;i<=n;i++){
if(count[i]==ans)//寻找与路径条数相同的点
cnt++;
}
if(ans==0)cout<<-1<<endl;
cout<<cnt-2<<endl;
}
2.
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
vector<int>vec[100005];
int n,m,a,b,k[100005];
void dfs(int n,int m){
if(k[n]) return;
k[n]=m;
for(int i=0;i<vec[n].size();++i){
dfs(vec[n][i],m);
}
}
int main(){
cin>>n>>m;
while(m--){
cin>>a>>b;
vec[b].push_back(a);
}
for(int i=n;i;--i){
dfs(i,i);
}
for(int i=1;i<=n;++i){
cout<<k[i]<<" ";
}
}
3.
#include <bits/stdc++.h>
using namespace std;
inline int read() //快速读取
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
int m, n;
const int N = 100005;
int a[N];
int t[2]; //记录颜色
bool vis[N];
vector<int> G[N];
bool dfs(int u, int color)
{
vis[u] = true; //标记当前点已经访问过
a[u] = color; //涂色
t[color]++; //该种颜色的数量加一
for (int i = 0; i < G[u].size(); i++) //遍历当前点的下一步能到达的所有点
{
int v = G[u][i]; //记录下一个点
if (vis[v] && a[v] == a[u]) //下一个点访问过而且颜色跟当前颜色相同
return 0; //就结束搜索,返回false
else if (vis[v]==0) //没访问过
{
bool flag = dfs(v, (color + 1) & 1); //将下一个点涂成不同颜色
if (flag==0) //涂色不成功
return 0;;; //就结束搜索,返回false
}
}
return 1;
}
int main()
{
n = read();;;;
m = read();
for (int i = 1; i <= m; i++)
{
int x = read(), y = read();
G[x].push_back(y); ;;//无向图
G[y].push_back(x);
}
int ans = 0;
for (int i = 1; i <= n; ++i)
if (!vis[i]) //如果该点没被标记
{
t[0] = t[1] = 0; //先将颜色数归零
bool flag = dfs(i, 0);
if (flag==0)
{
cout << "Impossible";
return 0;
}
ans=ans+ min(t[0], t[1]);;; //答案加上颜色数小的那个
}
cout << ans;
}
写这种题,一定要注意终止与判断条件。