• 图论总结


    ①DJ

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define e exit(0)
    #define re register
    #define inf 2147483647
    const int N = 10005;
    const int M = 500005; 
    int n,m,s,cnt,head[N],vis[N],dis[N];
    struct bian{int to,next,v;}len[M];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to,int v){
        len[++cnt].v = v;
        len[cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void DJ(){
        for(re int i=1;i<=n;++i)
            vis[i] = 0,dis[i] = inf;
        dis[s] = 0;
        priority_queue<pair<int,int> >Q;
        Q.push(make_pair(0,s));
        while(Q.size()){
            int now = Q.top().second;
            Q.pop();
            if(vis[now]) continue;
            vis[now] = 1;
            for(re int k=head[now];k;k=len[k].next){
                int to = len[k].to,v = len[k].v;
                if(dis[to] > dis[now]+v){
                    dis[to] = dis[now]+v;
                    Q.push(make_pair(-dis[to],to));
                }
            }
        }
     }
    int main()
    {
        freopen("P3371.in","r",stdin);
        freopen("P3371.out","w",stdout);
        n = fd(),m = fd(),s = fd();
        for(re int i=1;i<=m;++i){
            int x = fd(),y = fd(),v = fd();
            add(x,y,v);
        }
        DJ();
        for(re int i=1;i<=n;++i)
            printf("%d ",dis[i]);
        return 0;
    }
    View Code

     ②spfa

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define e exit(0)
    #define re register
    #define inf 2147483647
    const int N = 10005;
    const int M = 500005;
    int n,m,s,cnt,head[N],vis[N],dis[N];
    struct bian{int to,next,v;}len[M];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to,int v){
        len[++cnt].v = v;
        len[cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void spfa(){
        for(re int i=1;i<=n;++i)
            vis[i] = 0,dis[i] = inf;
        queue<int> Q;
        vis[s] = 1,dis[s] = 0;
        Q.push(s);
        while(Q.size()){
            int now = Q.front();
            Q.pop();vis[now] = 0;
            for(re int k=head[now];k;k=len[k].next){
                int to = len[k].to,v = len[k].v;
                if(dis[to] > dis[now]+v){
                    dis[to] = dis[now]+v;
                    if(!vis[to]){
                        vis[to] = 1;
                        Q.push(to);
                    }
                }
            }
        }
    }
    int main()
    {
        n = fd(),m = fd(),s = fd();
        for(re int i=1;i<=m;++i){
            int x = fd(),y = fd(),v = fd();
            add(x,y,v);
        }
        spfa();
        for(re int i=1;i<=n;++i)
            printf("%d ",dis[i]);
        return 0;
    }
    View Code

    ③Floyd

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    #define inf 2147483647
    int n,m,s,f[5010][5010];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    int main()
    {
        n = fd(),m = fd(),s = fd();
        for(re int i=0;i<5010;++i)
            for(re int j=0;j<5010;++j)
                if(i == j) f[i][j] = 0;
                else f[i][j] = inf;
        for(re int i=1;i<=m;++i){
            int x = fd(),y = fd(),v = fd();
            f[x][y] = min(f[x][y],v);
        }
        for(re int k=1;k<=n;++k)
            for(re int i=1;i<=n;++i)
                for(re int j=1;j<=n;++j){
                    if(f[i][k] == inf||f[k][j] == inf) continue;
                    f[i][j] = min(f[i][j],f[i][k]+f[k][j]);
                }
        for(re int i=1;i<=n;++i)
            printf("%d ",f[s][i]);
        return 0;
    }
    View Code

    ④最小生成树

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int N = 5005;
    const int M = 200005;
    int n,m,fa[N];
    long long ans;
    struct bian{int x,y,v;}len[M];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    int find(int x){
        if(x == fa[x]) return x;
        else return fa[x] = find(fa[x]);
    }
    bool cmp(bian a,bian b){return a.v < b.v;}
    int main()
    {
        freopen("P3366.in","r",stdin);
        freopen("P3366.out","w",stdout);
        n = fd(),m = fd();
        for(re int i=1;i<=n;++i)
            fa[i] = i;
        for(re int i=1;i<=m;++i)
            len[i].x = fd(),len[i].y = fd(),len[i].v = fd();
        sort(len+1,len+1+m,cmp);
        for(re int i=1;i<=m;++i){
            int fa1 = find(len[i].x),fa2 = find(len[i].y);
            if(fa1 != fa2){
                ans += len[i].v;
                fa[fa1] = fa2;
            }
        }
        printf("%lld",ans);
        return 0;
    }
    View Code

    ⑤树的直径

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int M = 50005;
    int n,m,cnt,ans,d[M],vis[M],head[M];
    struct bian{int to,next,v;}len[M<<1];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to,int v){
        len[++cnt].v = v;
        len[cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void dfs(int x){
        vis[x] = 1;
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to,v = len[k].v;
            if(vis[to]) continue;
            dfs(to);
            ans = max(ans,d[x]+d[to]+v);
            d[x] = max(d[x],d[to]+v);
        }
    }
    void work1(){
        dfs(1);
        printf("%d",ans);
    }
    int main()
    {
        freopen("P5021.in","r",stdin);
        freopen("P5021.out","w",stdout);
        n = fd(),m = fd();
        for(re int i=1;i<=n-1;++i){
            int x = fd(),y = fd(),v = fd();
            add(x,y,v),add(y,x,v);
        }
        if(m == 1){work1();return 0;}
        return 0;
    }
    View Code

     ⑥Lca

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int N = 5e5+5;
    int n,m,s,cnt,head[N],vis[N],dis[N],h[N],fa[N],bz[N][24];
    struct bian{int to,next;}len[N<<1];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void dfs(int x){
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            if(!h[to]){
                h[to] = h[x]+1;
                fa[to] = x;
                dfs(to);
            }
        }
    }
    void makebz(){
        for(re int i=1;i<=n;++i)
            bz[i][0] = fa[i];
        for(re int j=1;j<=20;++j)
            for(re int i=1;i<=n;++i)
                bz[i][j] = bz[bz[i][j-1]][j-1];
    }
    int Lca(int x,int y){
        if(h[x] <= h[y])
            swap(x,y);
        for(re int j=19;j>=0;--j)
            if(h[bz[x][j]] >= h[y])
                x = bz[x][j];
        if(x == y)
            return x;
        for(re int j=19;j>=0;--j)
            if(bz[x][j] != bz[y][j])
                x = bz[x][j],y = bz[y][j];
        return fa[x];
    }
    int main()
    {
        freopen("P3379.in","r",stdin);
        freopen("P3379.out","w",stdout);
        n = fd(),m = fd(),s = fd();
        for(re int i=1;i<=n-1;++i){
            int x = fd(),y = fd();
            add(x,y),add(y,x);
        }
        h[s] = s,fa[s] = s;
        dfs(s);makebz();
        while(m--){
            int a = fd(),b = fd();
            printf("%d
    ",Lca(a,b));
        }
        return 0;
    }
    View Code

    ⑦树的重心 NO1.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int M = 5e5+5;
    int n,cnt,ans,pos,head[M],size[M],vis[M];
    struct bian{int to,next;}len[M];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void dfs(int x){
        size[x] = vis[x] = 1;
        int max_part = 0;
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            if(vis[to]) continue;
            dfs(to);
            size[x] += size[to];
            max_part = max(max_part,size[to]);
        }
        max_part = max(max_part,n-size[x]);
        if(max_part < ans){
            ans = max_part;
            pos = x;
        }
    }
    int main()
    {
        freopen("kkk.in","r",stdin);
        freopen("kkk.out","w",stdout);
        n = fd();
        for(re int i=1;i<=n-1;++i){
            int x = fd(),y = fd();
            add(x,y);
        }
        dfs(1);
        printf("%d",pos);
        return 0;
    }
    View Code

     ⑧树的重心 NO2.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int M = 5e5+5;
    int n,cnt,vis[M],head[M],maxx[M],fa[M],bz[M][24],ans[M],size[M];
    struct bian{int to,next;}len[M<<1];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void dfs(int x){
        size[x] = vis[x] = 1;
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            if(vis[to]) continue;
            dfs(to);
            size[x] += size[to];
            maxx[x] = max(maxx[x],size[to]);
        }
    }
    void makebz(){
        for(re int j=1;j<=20;++j)
            for(re int i=1;i<=n;++i)
                bz[i][j] = bz[bz[i][j-1]][j-1];
    }
    void work(int x){
        int pos = x;
        for(re int j=19;j>=0;--j)
            if(bz[pos][j]&&maxx[x]*2-size[bz[pos][j]]>0)
                pos = bz[pos][j];
        if(pos != x) pos = fa[pos];
        while(pos&&size[x]*2-size[pos]>=0){
            if(maxx[x]*2-size[pos]<=0) ans[pos] = x;
            pos = fa[pos];
        }
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            work(to);
        }
    }
    int main()
    {
        freopen("kkk.in","r",stdin);
        freopen("kkk.out","w",stdout);
        n = fd();
        for(re int i=2;i<=n;++i){
            fa[i] = fd();
            bz[i][0] = fa[i];
            add(fa[i],i);
        }
        dfs(1);makebz();work(1);
        return 0;
    }
    View Code

    ⑨二分图最大匹配

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std; 
    #define re register
    const int M = 2001;
    int n,m,e,ans,Max,vis[M],match[M],check[M][M];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    bool Dfs(int x){
        for(re int j=n+1;j<=m+n;++j){
            if(!check[x][j]||vis[j]) continue;
            vis[j] = 1;
            if(!match[j]||Dfs(match[j])){
                match[j] = x;
                match[x] = j;
                return true;
            }
        }
        return false;
    }
    int main()
    {    
        freopen("P3386.in","r",stdin);
        freopen("P3386.out","w",stdout);
        n = fd(),m = fd(),e = fd();
        for(re int i=1;i<=e;++i){
            int x = fd(),y = fd();
            if(x > n||y > m) continue;
            y += n;
            check[x][y] = 1;
        }
        memset(match,0,sizeof(match));
        for(re int i=1;i<=n;++i){
            memset(vis,0,sizeof(vis));
            if(match[i]) continue;
            if(Dfs(i)) ++ans;
        }
        printf("%d",ans);
        return 0;
    }
    View Code

    二分图最佳匹配(最小费用最大流)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define e exit(0)
    #define re register
    #define inf 2147483647
    #define LL int
    const LL N = 1001;
    const LL M = 30005;
    LL n,m,cnt=1,s,t,sum,ans,head[N],dis[N],vis[N],pre[N];
    struct bian{LL from,to,v,flow,next;}len[M<<1];
    inline LL fd(){
        LL s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(LL from,LL to,LL flow,LL v){
        len[++cnt].v = v;
        len[cnt].to = to;
        len[cnt].flow = flow;
        len[cnt].from = from;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    bool spfa(){
        for(re LL i=0;i<=n;++i)
            pre[i] = -1,dis[i] = inf,vis[i] = 0;
        vis[1] = 1,dis[1] = 0;
        queue<LL> Q;
        Q.push(1);
        while(Q.size()){
            LL now = Q.front();
            Q.pop();
            vis[now] = 0;
            for(re LL k=head[now];k;k=len[k].next){
                if(len[k].flow <= 0) continue;
                LL to = len[k].to,v = len[k].v;
                if(dis[to] > dis[now]+v){
                    dis[to] = dis[now]+v;
                    pre[to] = k;
                    if(!vis[to]){
                        vis[to] = 1;
                        Q.push(to);
                    }
                }
            }
        }
        if(dis[n] == inf)
            return false;
        return true;
    }
    void costflow(){
        while(spfa()){
            LL Min = inf;
            for(re LL k=pre[n];k!=-1;k = pre[len[k].from])
                Min = min(Min,len[k].flow);
            sum += Min;
            for(re LL k=pre[n];k!=-1;k = pre[len[k].from]){
                ans += Min*len[k].v;
                len[k].flow -= Min;
                len[k^1].flow += Min;
            }
        }
        printf("%lld %lld",sum,ans);
    }
    int main()
    {
        freopen("LOJ102.in","r",stdin);
        freopen("LOJ102.out","w",stdout);
        n = fd(),m = fd();
        for(re LL i=1;i<=m;++i){
            LL x = fd(),y = fd(),flow = fd(),v = fd();
            add(x,y,flow,v),add(y,x,0,-v);
        }
        costflow();
        return 0;
    }
    View Code

    tarjan.缩点

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define re register
    const int N = 1e4+5;
    const int M = 1e5+5;
    int n,m,c,cnt,lx,deep,ans,top,head[N],col[N],H[N],in[N];
    int Q[N],dfn[N],low[N],vis[N],val[N],sum[N],f[N];
    struct bian{int from,to,next;}len[M];
    struct Eg{int to,next,v;}e[M];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to = to;
        len[cnt].from = from;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void con(int from,int to,int v){
        e[++lx].v = v;
        e[lx].to = to;
        e[lx].next = H[from];
        H[from] = lx;
    }
    void tarjan(int x){
        low[x] = dfn[x] = ++deep;
        Q[++top] = x;
        vis[x] = 1;
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            if(!dfn[to]){
                tarjan(to);
                low[x] = min(low[x],low[to]);
            }
            else if(vis[to])
                low[x] = min(low[x],dfn[to]);//防止连到兄弟边.
        }
        if(low[x] == dfn[x]){
            col[x] = ++c;
            sum[c] += val[x];
            vis[x] = 0;
            while(top&&Q[top] != x){
                vis[Q[top]] = 0;
                sum[c] += val[Q[top]];
                col[Q[top--]] = c;
            }
            --top;
        }
    }
    int main()
    {
        freopen("P3387.in","r",stdin);
        freopen("P3387.out","w",stdout);
        n = fd(),m = fd();
        for(re int i=1;i<=n;++i)
            val[i] = fd();
        for(re int i=1;i<=m;++i){
            int x = fd(),y = fd();
            add(x,y);
        }
        for(re int i=1;i<=n;++i)
            if(!dfn[i]) tarjan(i);
        for(re int i=1;i<=cnt;++i){
            int x = len[i].from,y = len[i].to;
            if(col[x] == col[y]) continue;
            int v = sum[col[y]];
            con(col[x],col[y],v);
            ++in[col[y]];
        }
        queue<int> Q;
        for(re int i=1;i<=c;++i){
            if(!in[i]) Q.push(i);
            f[i] = sum[i];
        }
        while(Q.size()){
            int now = Q.front();Q.pop();
            for(re int k=H[now];k;k=e[k].next){
                int to = e[k].to,v = e[k].v;
                f[to] = max(f[to],f[now]+v);
                --in[to];
                if(in[to] == 0) Q.push(to);
            }
        }
        for(re int i=1;i<=c;++i)
            ans = max(ans,f[i]);
        printf("%d",ans);
        return 0;
    }
    View Code

    tarjan.缩点

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int N = 20005;
    const int M = 100005;
    int n,m,cnt,deep,ans,head[N],cut[N],dfn[N],low[N];
    struct bian{int to,next;}len[M<<1];
    inline int fd(){
        int s=1,t=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void tarjan(int x,int rt,int fa){
        int lx = 0;
        dfn[x] = low[x] = ++deep;
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            if(to == fa) continue;
            if(!dfn[to]){ 
                if(x == rt) ++lx;
                tarjan(to,rt,x);
                low[x] = min(low[x],low[to]);
                if(low[to] >= dfn[x]&&x != rt)
                    cut[x] = 1;
            }
            else low[x] = min(low[x],dfn[to]);
        }
        if(x == rt&&lx >= 2)
            cut[x] = 1;
    }
    int main()
    {
        freopen("P3388.in","r",stdin);
        freopen("P3388.out","w",stdout);
        n = fd(),m = fd();
        for(re int i=1;i<=m;++i){
            int x = fd(),y = fd();
            add(x,y),add(y,x);
        }
        for(re int i=1;i<=n;++i)
            if(!dfn[i]) tarjan(i,i,i);
        for(re int i=1;i<=n;++i)
            if(cut[i] == 1) ++ans;
        printf("%d
    ",ans);
        for(re int i=1;i<=n;++i)
            if(cut[i] == 1) printf("%d ",i);
        return 0;
    }
    View Code

    tarjan.桥

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int N = 5e5+5;
    const int M = 5e5+5;
    int n,m,cnt,tot,deep,head[N],dfn[N],low[N],E[N][2];
    struct bian{int to,next;}len[M];
    inline int fd(){
        int s=1,t=0;
        char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
        while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to = to;
        len[cnt].next = head[from];
        head[from] = cnt;
    }
    void tarjan(int x,int fa){
        low[x] = dfn[x] = ++deep;
        for(re int k=head[x];k;k=len[k].next){
            int to = len[k].to;
            if(to == fa) continue;
            if(!dfn[to]){
                tarjan(to,x);
                low[x] = min(low[x],low[to]);
                if(low[to] > dfn[x])
                    E[++tot][0] = x,E[tot][1] = to;
            }
            else low[x] = min(low[x],dfn[to]);
        }
    }
    int main()
    {
        freopen("kkk.in","r",stdin);
        freopen("kkk.out","w",stdout);
        n = fd(),m = fd();
        for(re int i=1;i<=m;++i){
            int x = fd(),y = fd();
            add(x,y),add(y,x);
        }
        for(re int i=1;i<=n;++i)
            if(dfn[i]) tarjan(i,i);
        return 0;
    }
    View Code
  • 相关阅读:
    你看,那个人好像一条狗哎
    我竟然被抓去做了比特币挖矿工
    聊聊JAVA中 String类为什么不可变
    三分钟深入TT猫之故障转移
    shell实现两个数的相加
    shell截取字符串的方法
    Vi命令:如何删除全部内容?
    bash中不可以用字符串做数组下标
    awk打印出当前行的上一行
    awk同时处理多个文件
  • 原文地址:https://www.cnblogs.com/xqysckt/p/11863060.html
Copyright © 2020-2023  润新知