图论小知识
/*******************************************
邻接表 储存图
空间复杂度O(m+n)
时间复杂度O(m)
优点:
缺点:
********************************************/
#include<stdio.h>
#define MAXN 1111
#define MAXM 1111
int head[MAXN];//储存起点为Ui的位置
struct node
{
int from;//起点
int to; //终点
int cap;//权值
int next;//
}edge[MAXM];
int tot=0;
void add(int u, int v, int cap ,int rw =0 )//建边
{
node E = {u, v, cap, head[u]};
edge[ tot ] = E;
head[ u ] = tot++;
node E2 = {v, u, rw, head[v]}; //反向边
edge[ tot ] = E2;
head[ v ] = tot++;
}
int main()
{
for(i=1;i<=n;i++)
{
for(k=head[i];k!=-1;k=edge[k].next)
{
printf("%d %d %d\n",edge[j].from,edge[j].to,edge[j].cap);
}
}
}
欧拉回路:从一个点恰通过每条边一次 最终回到起点
条件:1.所有点都是连通的
2.(对于无向图)度数为奇数的点的个数为0 (对于有向图)每个点的入度==出度
变形欧拉图:可以不回到起点,经过所有边
条件:1.所有点都是连通的
2.(对于无向图)度数为奇数的点的个数为2(起点和终点)
(对于有向图)存在1个点的入度+1==出度(起点)
存在1个点的出度+1==入度(终点)
最小环证明:(可用floyd求)
一个环中的最大结点为k(编号最大),与他相连的两个点为i,j,这个环的最短长度为g[i][k]+g[k][j]+i到j的路径中,所有结点编号都小于k的最短路径长度
根据floyd的原理,在最外层循环做了k-1次之后,dist[i][j]则代表了i到j的路径中,所有结点编号都小于k的最短路径
综上所述,该算法一定能找到图中最小环
void dfs(int i, int j) {
int k = f[i][j];
if(k == 0) {
pash[num++] = j;
return ;
}
dfs(i, k);
dfs(k, j);
}
//---------------------------------------------------
for(k = 1; k <= n; ++k) {
for(i = 1; i < k; ++i) {
for(j = i + 1; j < k; ++j) {
if(ans > dis[i][j] + mp[i][k] + mp[k][j]) { //找最小环
ans = dis[i][j] + mp[i][k] + mp[k][j];
num = 0;
pash[num++] = i;
dfs(i, j);
pash[num++] = k;
}
}
}
for(i = 1; i <= n; ++i) {
for(j = 1; j <= n; ++j) {
if(dis[i][j] > dis[i][k] + dis[k][j]) {
dis[i][j] = dis[i][k] + dis[k][j];
f[i][j] = k; //f[i][j]记录i到j经过的点
}
}
}
}

浙公网安备 33010602011771号