zoukankan      html  css  js  c++  java
  • 【HAOI2017】新型城市化

    题面

    https://www.luogu.org/problem/P3731

    题解

    二分图上求可能割边。

    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<utility>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 10050
    #define M 150050
    #define INF 1000000007
    #define S 0
    #define T (n+1)
    #define LL long long
    #define ri register int
    using namespace std;
    
    int n,m,u[M],v[M];
    vector<int> to[N];
    int col[N],dfn[N];
    pair<int,int> ans[M];
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    struct graph {
      vector<int> ed[N];
      vector<int> w,to;
      int d[N],cur[N];
      int bel[N],dfn[N],low[N],cc,cnt;
      bool ins[N];
      stack<int> stk;
      void add_edge(int u,int v,int tw) {
        to.push_back(v); w.push_back(tw); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(0) ; ed[v].push_back(to.size()-1);
      }
      bool bfs() {
        queue<int> q;
        memset(d,0x3f,sizeof(d));
        d[S]=0; q.push(S);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<ed[x].size();i++) {
            int e=ed[x][i];
            if (d[x]+1<d[to[e]] && w[e]) {
              d[to[e]]=d[x]+1;
              q.push(to[e]);
            }
          }
        }
        return d[T]<INF;
      }
      int dfs(int x,int limit) {
        if (x==T || limit==0) return limit;
        int sum=0; 
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (w[e] && d[x]+1==d[to[e]]) {
            int f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            sum+=f; limit-=f; 
            w[e]-=f; w[1^e]+=f;
            if (!limit) return sum;
          }
        }
        return sum;
      }
      int dinic() {
        int ret=0;
        while (bfs()) {
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF);
        }
        return ret;
      }
      void tarjan(int x) {
        dfn[x]=low[x]=++cc;
        ins[x]=1; stk.push(x);
        for (ri i=0;i<ed[x].size();i++) {
          int e=ed[x][i];
          if (!w[e]) continue;
          if (dfn[to[e]]) {
            if (ins[to[e]]) low[x]=min(low[x],dfn[to[e]]);
          }
          else {
            tarjan(to[e]);
            low[x]=min(low[x],low[to[e]]);
          }
        }
        if (dfn[x]==low[x]) {
          int t; ++cnt;
          do {
            t=stk.top(); stk.pop(); ins[t]=0;
            bel[t]=cnt;
          }
          while (t!=x);
        }
      }
    } G;
    
    void dfs(int x,int s) {
      dfn[x]=1; col[x]=s;
      for (ri i=0;i<to[x].size();i++) {
        int y=to[x][i];
        if (!dfn[y]) dfs(y,s^1);
      }
    }
    
    int main(){
      n=read(); m=read();
      for (ri i=1;i<=m;i++) {
        u[i]=read(); v[i]=read();
        to[u[i]].push_back(v[i]); to[v[i]].push_back(u[i]);
      }
      for (ri i=1;i<=n;i++) if (!dfn[i]) dfs(i,0);
      for (ri i=1;i<=m;i++) {
        if (col[u[i]]) G.add_edge(u[i],v[i],1); else G.add_edge(v[i],u[i],1);
      }
      for (ri i=1;i<=n;i++) if (col[i]) G.add_edge(S,i,1); else G.add_edge(i,T,1);
      G.dinic();
      for (ri i=1;i<=n;i++) if (!G.dfn[i]) G.tarjan(i);
      int cc=0;
      for (ri i=0;i<G.w.size();i+=2) {
        if (G.bel[G.to[i^1]]!=G.bel[G.to[i]] && G.to[i^1]>=1 && G.to[i^1]<=n && G.to[i]>=1 && G.to[i]<=n && !G.w[i]) {
          ans[++cc]=make_pair(min(G.to[i^1],G.to[i]),max(G.to[i^1],G.to[i]));
        }
      }
      sort(ans+1,ans+cc+1);
      printf("%d
    ",cc);
      for (ri i=1;i<=cc;i++) printf("%d %d
    ",ans[i].first,ans[i].second);
      return 0;
    }
  • 相关阅读:
    理财课堂笔记第9天
    李筱懿的《先谋生,再谋爱》读后感
    bat想要写一个卸载软件的脚本,最后宣布失败[未完待续...]
    理财课堂日记第7天
    理财课堂日记第6天
    理财课堂日记第5天
    bat脚本登陆ftp服务器
    理财课堂笔记第4天
    理财课堂日记第3天
    理财课堂日记第2天
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11291298.html
Copyright © 2011-2022 走看看