赛用模板(图论)

迪杰斯特拉:

struct node{
    int id,val;
    node(int id,int val):id(id),val(val){}
    bool operator < (const node &a)const{
        return val>a.val;
    }
};
void add(int x,int y,int z){//双向边
    to[++now]=y;val[now]=z;nex[now]=head[x];head[x]=now;
    to[++now]=x;val[now]=z;nex[now]=head[y];head[y]=now;
}
priority_queue<node>  q;

void dijkstra(int st,int en){
    //如果只需要处理到en的距离,可能在塞入的时候判断与到en的距离,如果比dis[en]大就continue
    for(int i=1;i<=n;i++)dis[i]=inf;
    memset(vis,0,sizeof(vis));
    q.push(node(st,0));dis[st]=0;
    while(!q.empty()){
        int idx=q.top().id;q.pop();
        vis[idx]=1;
        for(int i=head[idx];~i;i=e[i].nex){
            if(vis[e[i].to])continue;
            if(dis[idx]<dis[e[i].to]-e[i].val){
                dis[e[i].to]=e[i].val+dis[idx];
                q.push(node(e[i].to,dis[e[i].to]));
            }
        }
    }
}

pair优化

vector<pill> v[N];

priority_queue<pill,vector<pill>,greater<pill> >Q;
int vis[N];
int dist[N];

int main(){
    memset(dist,125,sizeof(dist));
    int n=read(),m=read();
    for(int i=1;i<=m;i++){
        int a=read(),b=read(),c=read();
        v[a].pb(mk(b,c));v[b].pb(mk(a,c));
    }
    Q.push(mk(0,1));dist[1]=0;//(0,st)
    while(!Q.empty()){
        int j=Q.top().second;Q.pop();
        if(vis[j])continue;vis[j]=1;
        for(int i=0;i<v[j].size();i++){
            if(vis[v[j][i].first])continue;
            if(dist[v[j][i].first]>dist[j]+v[j][i].second){
                dist[v[j][i].first]=dist[j]+v[j][i].second;
                Q.push(mk(dist[v[j][i].first],v[j][i].first));
            }
        }
    }
    printf("%d\n",dist[n]);
} 

SPFA:

int spfa(int st,int en){
    for(int i=1;i<=qiang;i++){
        dist[i]=inf;
        vis[i]=0;
    }
    queue<int> q;
    dist[st]=0; vis[st]=1;
    q.push(st);
    while(!q.empty()){
        int now=q.front(); q.pop();
        vis[now]=0;
        for(int i=head[now];~i;i=e[i].next){
            int v=e[i].to,w=e[i].val;
            if(dist[v]>dist[now]+w){
                dist[v]=dist[now]+w;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(dist[en]>=inf) return -1;
    return dist[en];
}

二分图最大匹配:

int match[N];
bool vis[N];

int fin(int h){
    for(int i=0;i<=n;i++){//试图找到一个可以插入的空
        if(vis[i]||!link[h][i])continue;
        vis[i]=1;
        if(match[i]==0||fin(match[i])){
            match[i]=h;return 1;
        }
    }
    return 0;
}

int main(){
	memset(match,0,sizeof(match));
	...
	for(int i=1;i<=n;i++){
		memset(vis,0,sizeof(vis));
		if(fin(i))ans++;//最大匹配数
	}
}

拓扑排序字典序最小

int in_degree[509];
int M[509][509];
int vis[509];
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        int ans[500],ar=0;
        for(int i=1;i<=n;i++)in_degree[i]=0;
        memset(M,0,sizeof(M));memset(vis,0,sizeof(vis));
        while(m--){
            int a,b;scanf("%d%d",&a,&b);
            if(M[a][b]==0)in_degree[b]++;
            M[a][b]=1;
        }
        priority_queue<int,vector<int>,greater<int> >Q;
        for(int i=1;i<=n;i++)if(in_degree[i]==0){
            Q.push(i);vis[i]=1;
        }
        while(!Q.empty()){
            int t=Q.top();Q.pop();
            ans[++ar]=t;
            for(int i=1;i<=n;i++){
                if(vis[i]||M[t][i]==0)continue;
                in_degree[i]--;
                if(in_degree[i]==0){
                    Q.push(i);vis[i]=1;
                }
            }
        }
        if(ar!=n){printf("no\n");continue;}
        for(int i=1;i<=n;i++){
            printf("%d",ans[i]);
            if(i==n)printf("\n");
            else printf(" ");
        }
    }
}

最小生成树

struct node{
    int x,y,w;
    bool operator<(const node & a)const{
        return w<a.w;
    }
}edge[200005];
int fa[200005];
int fi(int t)
{   return fa[t]==t?fa[t]:fa[t]=fi(fa[t]);
}

int main()
{   int n,m,ans;
    while(scanf("%d%d",&n,&m)!=EOF)
    {   ans=0;
        for(int i=0;i<n;i++)fa[i]=i;
        for(int i=0;i<m;i++)
        {   int a,b,c;scanf("%d%d%d",&a,&b,&c);
            edge[i].x=a;edge[i].y=b;edge[i].w=c;
        }
        sort(edge,edge+m);
        for(int i=0;i<m;i++)
        {   int m1=edge[i].x,m2=edge[i].y;
            if(fi(m1)==fi(m2))continue;
            ans+=edge[i].w;
            fa[fi(m1)]=fi(m2);
        }
        cout<<ans<<endl;
    }
}

强连通

int n,numque=0,head[N],cnt,dfn[N],low[N],now,belong[N];
queue<int> que[N];
stack<int> sa;
struct edge{
    int next,to;
}e[N];
void add(int u,int v){
    e[cnt].to=v,e[cnt].next=head[u];
    head[u]=cnt++;
}
void init(){
    memset(head,-1,sizeof(head));
    memset(in,0,sizeof(in));
    numque=0,cnt=0,now=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(belong,0,sizeof(belong));
    while(!sa.empty()) sa.pop();

}
void tarjan(int x){
    dfn[x]=low[x]=++now;
    sa.push(x);
    for(int i=head[x];~i;i=e[i].next){
        int v=e[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if(!belong[i]) low[x]=min(low[x],low[v]);
    }
    if(dfn[x]==low[x]){
        numque++;
        while(1){
            int a=sa.top(); sa.pop();
            belong[a]=numque;
            que[numque].push(a);
            if(a==x) break;
        }
    }
}

K短路

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define LL long long
const int MAXN = 1100;
const int MAXM = 11000;
const int INF = 1e18;

struct EdgeNode{
    int to;
    LL w;
    int next;
}Edges[MAXM],Edges1[MAXM];

int Head[MAXN],Head1[MAXN];

struct Node{
    int to;
    LL g,f;
    bool operator < (const Node &r) const
    {
        if(r.f == f)
            return r.g < g;
        return r.f < f;
    }
};
int vis[MAXN];LL Dist[MAXN];

int A_Star(int start,int end,int N,int k){
    Node e,ne;
    int Cnt = 0;
    priority_queue<Node> que;
    if(start == end)
        k++;
    if(Dist[start] == INF)
        return -1;
    e.to = start;
    e.g = 0;
    e.f = e.g + Dist[e.to];
    que.push(e);
    while( !que.empty() ) {
        e = que.top();
        que.pop();
        if(e.to == end)
            Cnt++;
        if(Cnt == k)
            return e.g;

        for(int i = Head[e.to]; i != -1; i = Edges[i].next)   {
            ne.to = Edges[i].to;
            ne.g = e.g + Edges[i].w;
            ne.f = ne.g + Dist[ne.to];
            que.push(ne);
        }
    }
    return -1;
}
void SPFA(int s,int N){
    for(int i = 0; i <= N; ++i)
        Dist[i] = INF;
    memset(vis,0,sizeof(vis));
    vis[s] = 1;
    Dist[s] = 0;
    queue<int> Q;
    Q.push(s);
    while( !Q.empty() ) {
        int u = Q.front();
        Q.pop();
        vis[u] = 0;
        for(int i = Head1[u]; i != -1; i = Edges1[i].next)   {
            int temp = Dist[u] + Edges1[i].w;
            if(temp < Dist[Edges1[i].to])     {
                Dist[Edges1[i].to] = temp;
                if(!vis[Edges1[i].to])   {
                    vis[Edges1[i].to] = 1;
                    Q.push(Edges1[i].to);
                }
            }
        }
    }
}

int main(){
    int N,M,u,v,s,t,k;LL LIM,w;
    while(~scanf("%d%d",&N,&M)) {
        memset(Edges,0,sizeof(Edges));
        memset(Edges1,0,sizeof(Edges1));
        memset(Head,-1,sizeof(Head));
        memset(Head1,-1,sizeof(Head1));

        scanf("%d%d%d%lld",&s,&t,&k,&LIM);
        //LIM为k短路的下限,之和题目有关,与算法无关
        for(int i = 0; i < M; ++i)    {
            scanf("%d%d%lld",&u,&v,&w);
            Edges[i].to = v;
            Edges[i].w = w;
            Edges[i].next = Head[u];
            Head[u] = i;

            Edges1[i].to = u;
            Edges1[i].w = w;
            Edges1[i].next = Head1[v];
            Head1[v] = i;
        }
        SPFA(t,N);
        LL ans = A_Star(s,t,N,k);//不为-1即为k短路
        if(ans==-1||ans>LIM)printf("Whitesnake!\n");
        else printf("yareyaredawa\n");
    }

    return 0;
}

最大流

const int Ni = 510;
const int MAX = 1<<26;
struct Edge{
    int u,v,c;
    int next;
}edge[20*Ni];
int n,m;
int edn;//边数
int p[Ni];//父亲
int d[Ni];
int sp,tp;//原点,汇点

void addedge(int u,int v,int c)
{
    edge[edn].u=u; edge[edn].v=v; edge[edn].c=c;
    edge[edn].next=p[u]; p[u]=edn++;

    edge[edn].u=v; edge[edn].v=u; edge[edn].c=0;
    edge[edn].next=p[v]; p[v]=edn++;
}
int bfs()
{
    queue <int> q;
    memset(d,-1,sizeof(d));
    d[sp]=0;
    q.push(sp);
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        for(int i=p[cur];i!=-1;i=edge[i].next)
        {
            int u=edge[i].v;
            if(d[u]==-1 && edge[i].c>0)
            {
                d[u]=d[cur]+1;
                q.push(u);
            }
        }
    }
    return d[tp] != -1;
}
int dfs(int a,int b)
{
    int r=0;
    if(a==tp)return b;
    for(int i=p[a];i!=-1 && r<b;i=edge[i].next)
    {
        int u=edge[i].v;
        if(edge[i].c>0 && d[u]==d[a]+1)
        {
            int x=min(edge[i].c,b-r);
            x=dfs(u,x);
            r+=x;
            edge[i].c-=x;
            edge[i^1].c+=x;
        }
    }
    if(!r)d[a]=-2;
    return r;
}

int dinic(int sp,int tp)
{
    int total=0,t;
    while(bfs())
    {
        while(t=dfs(sp,MAX))
        total+=t;
    }
    return total;
}

int main()
{

    sp=402,tp=401;
    int i,u,v,c;
    int a,b;
    scanf("%d%d%d",&n,&a,&b);
    edn=0;//初始化
    memset(p,-1,sizeof(p));
    for(int i=1;i<=a;i++)addedge(402,i,1);
    for(int i=1;i<=b;i++)addedge(i+300,401,1);
    for(int i=1;i<=n;i++)addedge(i+100,i+200,1);
    for(i=1;i<=n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        while(x--){
            int tmp;
            scanf("%d",&tmp);
            addedge(tmp,i+100,1);
        }
        while(y--){
            int tmp;
            scanf("%d",&tmp);
            addedge(i+200,tmp+300,1);
        }
    }
    printf("%d\n",dinic(402,401));

    return 0;
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/82782843
今日推荐