【loj】#6002. 「网络流 24 题」最小路径覆盖

来源:互联网 发布:科技部办公厅关于优化 编辑:程序博客网 时间:2024/06/05 20:01

记录一个菜逼的成长。。

题目链接
hihocoder

//#define debug#include <bits/stdc++.h>using namespace std;#define ALL(v) (v).begin(),(v).end()#define cl(a,b) memset(a,b,sizeof(a))#define clr clear()#define pb push_back#define mp make_pair#define fi first#define se second#define fin freopen("D://in.txt","r",stdin)#define fout freopen("D://out.txt","w",stdout)#define lson t<<1,l,mid#define rson t<<1|1,mid+1,r#define seglen(t) (node[t].r-node[t].l+1)#define lowbit(x) (x)&(-x)typedef long long LL;typedef pair<int,int> PII;const int INF = 0x3f3f3f3f;//O(N^2*M)const int MAX_V = 500 + 10;struct edge{    int to,cap,rev;    edge(){}    edge(int _to,int _cap,int _rev):to(_to),cap(_cap),rev(_rev){}};vector<edge>G[MAX_V];int level[MAX_V];int iter[MAX_V];void add(int from,int to,int cap){    G[from].push_back(edge(to,cap,G[to].size()));    G[to].push_back(edge(from,0,G[from].size()-1));}void bfs(int s){    memset(level,-1,sizeof(level));    queue<int>que;    level[s] = 0;    que.push(s);    while(!que.empty()){        int f = que.front();        que.pop();        for( int i = 0; i < G[f].size(); i++ ){            edge &e = G[f][i];            if(e.cap > 0 && level[e.to] == -1){                level[e.to] = level[f] + 1;                que.push(e.to);            }        }    }}int dfs(int v,int t,int f){    if(v == t)return f;    for( int &i = iter[v]; i < G[v].size(); i++ ){        edge &e = G[v][i];        if(e.cap > 0 && level[v] < level[e.to]){            int d = dfs(e.to,t,min(e.cap,f));            if(d > 0){                e.cap -= d;                G[e.to][e.rev].cap += d;                return d;            }        }    }    return 0;}int max_flow(int s,int t){    int flow = 0;    for(;;){        bfs(s);        if(level[t] == -1)return flow;        memset(iter,0,sizeof(iter));        int f;        while((f = dfs(s,t,INF)) > 0)            flow += f;    }}int nxt[MAX_V];int main(){  int n,m;  scanf("%d%d",&n,&m);  int s = 0, t = n + n + 1;  for( int i = 1; i <= n; i++ )add(s,i,1),add(i+n,t,1);  for( int i = 1; i <= m; i++ ){    int u,v;    scanf("%d%d",&u,&v);    add(u,v+n,1);  }  vector<int>a;  int ret = max_flow(s,t);  for( int i = 1; i <= n; i++ ){    for( int j = 0; j < G[i].size(); j++ ){      if(G[i][j].to > n && G[i][j].cap == 0){        nxt[i] = G[i][j].to - n;        break;      }    }  }  //找出路径起点  for( int i = 1; i <= n; i++ ){    for( int j = 0; j < G[i+n].size(); j++ ){      if(G[i+n][j].to == t && G[i+n][j].cap == 1){        a.pb(i);        break;      }    }  }  for( int i = 0; i < a.size(); i++ ){    printf("%d ",a[i]);    while(nxt[a[i]]){      printf("%d ",nxt[a[i]]);      a[i] = nxt[a[i]];    }    puts("");  }  printf("%d\n",n - ret);  return 0;}
阅读全文
0 0
原创粉丝点击