HDU 2485 Destroying the bus stations
2015 ACM / ICPC 北京站 热身赛 C题
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int maxn=50+10;//点的数量 int n,m,k; int u[4000+10],v[4000+10]; int dis1[maxn],dis2[maxn]; bool flag1[maxn],flag2[maxn]; vector<int>P[maxn]; vector<int>FP[maxn]; queue<int>Q1; queue<int>Q2; struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f) {} }; vector<Edge>edges; vector<int>G[maxn*2]; bool vis[maxn*2]; int d[maxn*2]; int cur[maxn*2]; int s, t; void read() { for(int i=1;i<=m;i++) { scanf("%d%d",&u[i],&v[i]); P[u[i]].push_back(v[i]); FP[v[i]].push_back(u[i]); } } void init() { for(int i=0;i<maxn;i++) P[i].clear(); for(int i=0;i<maxn;i++) FP[i].clear(); for(int i=1;i<=n;i++) dis1[i]=INF,dis2[i]=INF; for(int i = 0; i < 2*maxn; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); int w = edges.size(); G[from].push_back(w - 2); G[to].push_back(w - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int>Q; Q.push(s); d[s] = 0; vis[s] = 1; while (!Q.empty()) { int x = Q.front(); Q.pop(); for (int i = 0; i<G[x].size(); i++) { Edge e = edges[G[x][i]]; if (!vis[e.to] && e.cap>e.flow) { vis[e.to] = 1; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if (x == t || a == 0) return a; int flow = 0, f; for (int &i = cur[x]; i<G[x].size(); i++) { Edge e = edges[G[x][i]]; if (d[x]+1 == d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { edges[G[x][i]].flow+=f; edges[G[x][i] ^ 1].flow-=f; flow+=f; a-=f; if(a==0) break; } } if(!flow) d[x] = -1; return flow; } int dinic(int s, int t) { int flow = 0; while (BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; } void spfa1(int x) { while(!Q1.empty()) Q1.pop(); memset(flag1,0,sizeof flag1); dis1[x]=0; flag1[x]=1; Q1.push(x); while(!Q1.empty()) { int h=Q1.front(); flag1[h]=0; Q1.pop(); for(int i=0;i<P[h].size();i++) { if(dis1[h]+1<dis1[P[h][i]]) { dis1[P[h][i]]=dis1[h]+1; if(flag1[P[h][i]]==0) { flag1[P[h][i]]=1; Q1.push(P[h][i]); } } } } } void spfa2(int x) { while(!Q2.empty()) Q2.pop(); memset(flag2,0,sizeof flag2); dis2[x]=0; flag2[x]=1; Q2.push(x); while(!Q2.empty()) { int h=Q2.front(); flag2[h]=0; Q2.pop(); for(int i=0;i<FP[h].size();i++) { if(dis2[h]+1<dis2[FP[h][i]]) { dis2[FP[h][i]]=dis2[h]+1; if(flag2[FP[h][i]]==0) { flag2[FP[h][i]]=1; Q2.push(FP[h][i]); } } } } } int main() { while(~scanf("%d%d%d",&n,&m,&k)) { if(!n&&!m&&!k) break; init(); read(); spfa1(1); spfa2(n); s=1;t=n+n; for(int i=1;i<=n;i++) AddEdge(i+n,i,1); for(int i=1;i<=m;i++) if(dis1[u[i]]+dis2[v[i]]+1<=k) AddEdge(u[i],v[i]+n,INF); int ans=dinic(s,t); printf("%d\n",ans); } return 0; }