1. 程式人生 > >luogu2764 最小路徑覆蓋問題

luogu2764 最小路徑覆蓋問題

ron int pan oid main printf != gpo n)

最小路徑覆蓋,看這裏

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
struct Edge{
    int too, nxt, val;
}edge[15005];
int n, m, hea[305], ss, tt, uu, vv, maxFlow, lev[305], cnt;
const int oo=0x3f3f3f3f;
bool vis[305];
queue<int> d;
void add_edge(int
fro, int too, int val){ edge[cnt].nxt = hea[fro]; edge[cnt].too = too; edge[cnt].val = val; hea[fro] = cnt++; } void addEdge(int fro, int too, int val){ add_edge(fro, too, val); add_edge(too, fro, 0); } bool bfs(){ memset(lev, 0, sizeof(lev)); d.push(ss); lev[ss] = 1
; while(!d.empty()){ int x=d.front(); d.pop(); for(int i=hea[x]; i!=-1; i=edge[i].nxt){ int t=edge[i].too; if(!lev[t] && edge[i].val>0){ lev[t] = lev[x] + 1; d.push(t); } } } return
lev[tt]!=0; } int dfs(int x, int lim){ if(x==tt) return lim; int addFlow=0; for(int i=hea[x]; i!=-1 && addFlow<lim; i=edge[i].nxt){ int t=edge[i].too; if(lev[t]==lev[x]+1 && edge[i].val>0){ int tmp=dfs(t, min(lim-addFlow, edge[i].val)); edge[i].val -= tmp; edge[i^1].val += tmp; addFlow += tmp; } } return addFlow; } void dinic(){ while(bfs()) maxFlow += dfs(ss, oo); } void prt(int x){ vis[x] = true; printf("%d ", x); for(int i=hea[x]; i!=-1; i=edge[i].nxt){ int t=edge[i].too; if(t>=1 && edge[i^1].val) prt(t-n); } } int main(){ memset(hea, -1, sizeof(hea)); cin>>n>>m; ss = 0; tt = 2 * n + 1; for(int i=1; i<=n; i++){ addEdge(ss, i, 1); addEdge(i+n, tt, 1); } for(int i=1; i<=m; i++){ scanf("%d %d", &uu, &vv); addEdge(uu, vv+n, 1); } dinic(); for(int i=1; i<=n; i++){ if(vis[i]) continue; bool flag=false; for(int j=hea[i]; j!=-1; j=edge[j].nxt) if(edge[j^1].val){ flag = true; break; } if(flag) prt(i); printf("\n"); } cout<<n-maxFlow<<endl; return 0; }

luogu2764 最小路徑覆蓋問題