版权声明:代码原创,如需转载,请发邮箱至[email protected]或[email protected],或qq3145743347. https://blog.csdn.net/ebirth/article/details/91354290
图论问题概述总结(2)
对于图论,我们尊熟悉的算法是比较多的,这次,我就找了集中常用的算法。
- 欧拉回路
欧拉回路就是在一张有向或无向图中求出一笔画问题的具体画法。
方法:
- 先思考此题是否是用欧拉回路来解决。
- 思考是有向图或无向图来解决适用于欧拉回路。
- 对于有向图,保证每个点的入度为出度;对于系数图,保证每个点为偶数。
我们对于这个算法,可以用来图:
就向这样,接下来,我们看看代码:
题:http://120.77.248.79/problem/3023105
#include<bits/stdc++.h>
using namespace std;
const int maxn=200000;
const int maxm=200000;
struct node{
int v,next;
int len;
}e[maxm];
int g[maxn],ans;
void init(){
memset(g,-1,sizeof(g));
ans=0;
}
void add(int u,int v){
e[ans].v=v;
e[ans].next=g[u];
g[u]=ans++;
}
int n,m;
int degree[maxn];
int cnt;
bool vis[maxn];
void dfs(int u){
vis[u]=true;
cnt++;
for (int i=g[u];i!=-1;i=e[i].next){
int v=e[i].v;
if (!vis[v]){
dfs(v);
}
}
}
void euler(){
dfs(1);
if(cnt!=n){
cout<<0<<endl;
return;
}
int tot=0;
for(int i=1;i<=n;i++){
if(degree[i]%2==1){
tot++;
}
}
if(tot==0){
cout<<"1"<<endl;
}else{
cout<<"0"<<endl;
}
}
int main(){
init();
memset(degree,0,sizeof(degree));
cin>>n>>m;
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
degree[u]++;
degree[v]++;
}
euler();
return 0;
}
这就是题欧拉回路的做法,这是他的基本思维,接下来,我们看看一道题:https://www.luogu.org/problemnew/show/P2731
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int g[1010][1010];
int a[100000],b[100000];
int ans;
int s=1000000,q=1000000;
void add(int x){
for(int i=1;i<=500;i++){
if(g[x][i]){
g[x][i]--;
g[i][x]--;
add(i);
}
}
b[ans--]=x;
}
int main(){
cin>>n;
ans=n+1;
for(int i=1;i<=n;i++){
int u,v;
cin>>u>>v;
g[u][v]++;
g[v][u]++;
a[u]++;
a[v]++;
s=min(s,min(u,v));
}
for(int i=1;i<=500;i++){
if(a[i]%2==1){
q=min(i,q);
}
if(q<1000000){
add(q);
}else{
add(s);
}
}
for(int i=1;i<=n+1;i++){
cout<<b[i]<<endl;
}
return 0;
}
同理,于欧拉回路的思路是一样的。
下期见,下棋(拓普排序)
这期完毕,下棋在讲。