图论

欧拉回路

定义:给定无孤立结点图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次,称这条回路为欧拉回路。具有欧拉回路的图成为欧拉图。

欧拉回路存在的充要条件: 每个点的度为偶数(无向图) 每个点的入度出度相等(有向图)

欧拉路存在的必要条件: 有且仅有两个点的度为奇数(无向图) 总的入度和等于总的出度和,有且仅有两个点的入度、出度差为1,其他点相等(有向图)

匈牙利算法

最大需要**多少次?最多能匹配多少对?能否完全匹配?

洛谷P2756 飞行员配对方案问题

/*
    匈牙利算法求最大匹配数,link数组可以直接输出方案 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 210
using namespace std;
int n,m,num,head[maxn],link[maxn];
bool vis[maxn];
struct node{
    int to,pre;
}e[maxn];
void Insert(int from,int to){
    e[++num].to=to;
    e[num].pre=head[from];
    head[from]=num;
}
bool dfs(int x){
    for(int i=head[x];i;i=e[i].pre){
        int to=e[i].to;
        if(vis[to]==0){
            vis[to]=1;
            if(link[to]==0||dfs(link[to])){
                link[to]=x;return 1;
            }
        }
    }
    return 0;
}
int main(){
    scanf("%d%d",&m,&n);
    int x,y;
    while(1){
        scanf("%d%d",&x,&y);
        if(x==-1&&y==-1)break;
        Insert(x,y);
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))ans++;
    }
    if(ans==0){
        printf("No Solution!");
        return 0;
    }
    printf("%d\n",ans);
    for(int i=1;i<=n;i++){
        if(link[i]){
            printf("%d %d\n",link[i],i);
        }
    }
}
最大匹配数+方案

洛谷P1129 [ZJOI2007]矩阵游戏 

考虑如何建模,首先这是一个矩阵,矩阵上常用的建模是分离横纵坐标,根据对应位置上的数值连线

最终状态是(1,1)(2,2)...(n,n)都有一个点,我们把点看成匹配边的话,就是每行和每列都做到了匹配,换言之就是N个行和N个列都有匹配时,一定能转换成最终状态,所以就如S向每行所对应的点连边,每列所对应的点向T连边,每个1的块就是某行和某列的边,再逆过来转换到初始状态,我们发现交换行本质就是交换S向这两行连的边,所以匹配数不变,同理交换列也是
举个例子来说吧,如果有一行里有两个1,那么我们无论怎么交换行和列这两个一永远在同一行里,匹配数不变

最短路

 

posted @ 2017-09-23 20:31  Echo宝贝儿  阅读(173)  评论(0编辑  收藏  举报