图的遍历
``
#include<bits/stdc++.h>
using namespace std;
vector<int> ve[100050];//存图
int res[100005]={0}; //记录最大值
//简化:反向建图
//能到达的最大点->能否对当前的最大点
//从最大值开始搜索:目前能走过的点一定是最大点
void dfs(int x,int y)
{
if(res[x]!=0) return;
res[x]=y;
for(int j=0;j<ve[x].size();j++)
{
int next=ve[x][j];
dfs(next,y);
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=m;i>=1;i--)
{
int u,v;
cin>>u>>v;
ve[v].push_back(u);//反向建图
}
//从最大值开始搜索
for(int i=n;i>0;i--)
{dfs(i,i);}
for(int j=1;j<=n;j++)
{cout<<res[j]<<" ";}
return 0;
}
封锁阳光大学
- 每条道路有且只有一个被标记
- 染色问题:拿颜色染:每边颜色不一
- 记录每个端点的颜色
- dfs :搜索每一个点【一个一个子树搜】
#include<iostream>
#include<vector>
using namespace std;
int vis[100050]={0};
int col[2]={0};
//对应哪种颜色
vector<int>ma[10050];
//假如 染色过了
void dfs(int x)
{
if(vis[x]==1) col[0]++;
if(vis[x]==2) col[1]++;
for(int i=0;i<ma[x].size();i++)
{
int next=ma[x][i];
//出现重复染色->无法达成
if(vis[next] == vis[x])
{
cout<<"Impossible";
exit(0); //!!返回文件末尾【表示正常结束】
}
if(vis[next]!=0)
continue;
if(vis[next]==0)
{
//涂相反颜色
if(vis[x]==1)
vis[next]=2;
else
vis[next]=1;
//查找下一个点
dfs(next);
}
}
}
int main()
{
int m,n;
int ans=0;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
ma[u].push_back(v);
ma[v].push_back(u);
}
for(int i=1;i<=n;i++)
{
//已经染过色
if(vis[i]!=0)
{
continue;
}
//未染过色
vis[i]=1;
col[0]=0;
col[1]=0;
//搜索点
dfs(i);
ans+= min(col[1],col[0]);
}
cout<<ans;
return 0;
}