沈阳预选赛的1011,刚开始没想到用bfs找最短路,还找了一个能找出全部多条最短路径的板子,结果一直犹豫最短路+网络流会不会超时,到了也没写完这题。ios
Input算法
Output网络
Sample Inputless
1 4 4 1 2 1 2 4 2 3 1 3 4 3 4
Sample Outputide
4
题解:这里由于它全部路径的长度都为1,因此不须要什么算法去实现找多条最短路,只须要用bfs给点标号,由bfs的最优解特性可知,它找到的必定是最短路上的点,当搜完一遍后,用深搜再搜一遍,将全部知足dis[v]=dis[u]+1,的点建图造成一个新的网络,这样咱们就能够在新网络上裸最大流了,因为他要求用最少的木头去建造障碍物,实际上就是求这张网络带源点的点集和带汇点的点集之间的最小割,也就是最大流,这样就是裸模板了。ui
代码:this
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <cmath> #include <vector> #include <queue> #define MEMINF(a) memset(a,0x3f,sizeof a) #define MEM(a,b) memset(a,b,sizeof a) using namespace std; typedef long long LL; const int MAXN=1e5+10; const int MAXM=4e5+10; const int INF=0x3f3f3f3f; struct MaxFlow{ int head[MAXN]; struct Edge{ int u,v,nex,cap,flow; }edge[MAXM]; int tot,s,t,n,m; int dis[MAXN]; int cur[MAXN]; void Dinic_init(int n,int m){ this->s=n; this->t=1; this->n=n; this->m=m; MEM(head,-1); tot=0; } void Addedge(int u,int v,int w) { edge[tot].v=v,edge[tot].cap=w,edge[tot].flow=0,edge[tot].nex=head[u],head[u]=tot++; edge[tot].v=u,edge[tot].cap=0,edge[tot].flow=0,edge[tot].nex=head[v],head[v]=tot++; } bool bfs() { MEM(dis,-1); queue<int>q; dis[s]=0; q.push(s); while (!q.empty()) { int u=q.front(); q.pop(); for (int i=head[u]; ~i; i=edge[i].nex) { int v=edge[i].v; if (edge[i].cap>edge[i].flow&&dis[v]==-1) { q.push(v); dis[v]=dis[u]+1; } } } return dis[t]!=-1; } int dfs(int u,int delta) { if (u==t||delta==0) return delta; int ret=0; int aug; for(int &i=cur[u]; ~i; i=edge[i].nex) { int v=edge[i].v; if (dis[v]==dis[u]+1&&(aug=dfs(v,min(edge[i].cap-edge[i].flow,delta)))>0) { edge[i].flow+=aug; edge[i^1].flow-=aug; delta-=aug; ret+=aug; if (delta==0) break; } } return ret; } void dinic() { int ret=0; while(bfs()) { memcpy(cur,head,sizeof head); ret+=dfs(s,INF); //cout<<ret<<endl; } cout<<ret<<endl; } }nima; struct Search_{ int head[MAXN]; int level[MAXN]; int tot; int s; int vis[MAXN]; struct Edge { int u,v,w; int nex; }edge[MAXM]; void Addedge(int u,int v,int w) { edge[tot].v=v;edge[tot].u=u;edge[tot].w=w;edge[tot].nex=head[u],head[u]=tot++; edge[tot].v=u;edge[tot].u=v;edge[tot].w=w;edge[tot].nex=head[v],head[v]=tot++; } void search_init(int n) { MEM(level,-1); tot=0; MEM(head,-1); MEM(vis,0); this->s=n; } void bfs() { queue<int>q; level[s]=0; q.push(s); while (!q.empty()) { int u=q.front(); q.pop(); for (int i=head[u]; ~i; i=edge[i].nex) { int v=edge[i].v; if (level[v]==-1) { level[v]=level[u]+1; q.push(v); } } } } void dfs(int u) { vis[u]=1; for (int i=head[u]; ~i; i=edge[i].nex) { int v=edge[i].v; if (level[v]==level[u]+1) { //printf("u:%d v:%d w:%d\n",u,v,edge[i].w); nima.Addedge(u,v,edge[i].w); if (!vis[v]) dfs(v); } } } void search_work() { bfs(); dfs(s); return; } }cao; int main(){ int n,m; int Test; cin>>Test; while (Test--){ scanf("%d %d",&n,&m); int u,v,w; cao.search_init(n); nima.Dinic_init(n,m); for (int i=0; i<m; ++i) { scanf("%d %d %d",&u,&v,&w); cao.Addedge(u,v,w); } cao.search_work(); nima.dinic(); } }