标签:des style http color os io strong for
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9658 | Accepted: 2859 |
Description
Input
Output
Sample Input
7 9 2 1 2 2 2 3 5 3 7 5 1 4 1 4 3 1 4 5 7 5 7 1 1 6 3 6 7 3
Sample Output
5
Hint
Source
题目大意:
FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l。现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路不能与先前的路径重复,问这些路径中的最长路的最小是多少。
解题思路:
解题代码:二分+网络流。
代码一:DINIC算法
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <cmath> #include <algorithm> using namespace std; const int INF=(1<<30); const int maxn=210,maxm=201000; struct edge{ int u,v,f,next; edge(int u0=0,int v0=0,int f0=0){ u=u0;v=v0;f=f0; } }e[maxm]; int src,sink,cnt,head[maxn]; void adde(int u,int v,int f){ e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].next=head[u],head[u]=cnt++; e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].next=head[v],head[v]=cnt++; } void init(){ cnt=0; memset(head,-1,sizeof(head)); } queue <int> q; bool visited[maxn]; int dist[maxn]; void bfs(){ memset(dist,0,sizeof(dist)); while(!q.empty()) q.pop(); visited[src]=true; q.push(src); while(!q.empty()){ int s=q.front(); q.pop(); for(int i=head[s];i!=-1;i=e[i].next){ int d=e[i].v; if(e[i].f>0 && !visited[d]){ q.push(d); dist[d]=dist[s]+1; visited[d]=true; } } } } int dfs(int u,int delta){ if(u==sink) return delta; else{ int ret=0; for(int i=head[u];delta && i!=-1;i=e[i].next){ if(e[i].f>0 && dist[e[i].v]==dist[u]+1){ int d=dfs(e[i].v,min(e[i].f,delta)); e[i].f-=d; e[i^1].f+=d; delta-=d; ret+=d; } } if(!ret) dist[u]=-2; return ret; } } int maxflow(){ int ret=0; while(true){ memset(visited,false,sizeof(visited)); bfs(); if(!visited[sink]) return ret; ret+=dfs(src,INF); } return ret; } int n,m,num,maxr,minr; vector <edge> vec; void input(){ maxr=0; minr=INF; src=1,sink=n; vec.clear(); int u,v,w; for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&w); vec.push_back(edge(u,v,w)); vec.push_back(edge(v,u,w)); if(w>maxr) maxr=w; if(w<minr) minr=w; } } void build(int dis0){ init(); for(int i=0;i<vec.size();i++){ if(vec[i].f<=dis0){ adde(vec[i].u,vec[i].v,1); } } } void solve(){ int l=minr,r=maxr; while(l<r){ int mid=(l+r)/2; build(mid); if(maxflow()>=num) r=mid; else l=mid+1; } printf("%d\n",r); } int main(){ while(scanf("%d%d%d",&n,&m,&num)!=EOF){ input(); solve(); } return 0; }
代码二:sap算法
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define INF 2000000000 #define N 100010 typedef long long ll; const int maxn=210; struct edge{ int u,v,next,cap; edge(int u0=0,int v0=0,int f0=0){ u=u0;v=v0;cap=f0; } }e[210000]; int n,head[N],tol,top,st[N]; int src,des,dep[N],gap[N]; void adde(int u,int v,int c){ e[tol].u=u,e[tol].v=v,e[tol].next=head[u],e[tol].cap=c,head[u]=tol++; e[tol].u=v,e[tol].v=u,e[tol].next=head[v],e[tol].cap=0,head[v]=tol++; } void bfs(){//对于反边计算层次 for(int i=0;i<N;i++) dep[i]=N-1; memset(gap,0,sizeof gap); gap[0]=1,dep[des]=0; int q[N],l=0,r=0,u,v; q[r++]=des; while(l!=r){ u=q[l++]; l=l%N; for(int i=head[u];i!=-1;i=e[i].next){ v=e[i].v; if(e[i].cap!=0||dep[v]!=N-1) continue; q[r++]=v; r=r%N; ++gap[dep[v]=dep[u]+1]; } } } int sap(){ bfs(); int u=src,s[N],top=0,res=0,ii; int cur[N]; memcpy(cur,head,sizeof head); while(dep[src]<n){ if(u==des){//求得一条增广路 int minf=INF,pos=n; for(int i=0;i<top;i++){ if(minf>e[s[i]].cap){ minf=e[s[i]].cap; pos=i; } } for(int i=0;i<top;i++){ e[s[i]].cap-=minf; e[s[i]^1].cap+=minf; } top=pos; res+=minf; u=e[s[top]].u;//优化1 } if(dep[u]!=0&&gap[dep[u]-1]==0) break;//出现断层 ii=-1; for(int i=cur[u];i!=-1;i=e[i].next){ if(dep[e[i].v]==N-1) continue; if(e[i].cap!=0&&dep[u]==dep[e[i].v]+1){ii=i;break;} } if(ii!=-1){//有允许弧 cur[u]=ii; s[top++]=ii; u=e[ii].v; }else{//不断回退找增光路 int mind=n; for(int i=head[u];i!=-1;i=e[i].next){ if(e[i].cap==0) continue; if(dep[e[i].v]<mind) mind=dep[e[i].v],cur[u]=i; } --gap[dep[u]]; ++gap[dep[u]=mind+1];//优化2 if(u!=src) u=e[s[--top]].u; } } return res; } int m,num,maxr,minr; vector <edge> vec; void input(){ maxr=0; minr=INF; vec.clear(); int u,v,w; for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&w); vec.push_back(edge(u,v,w)); vec.push_back(edge(v,u,w)); if(w>maxr) maxr=w; if(w<minr) minr=w; } } void build(int dis0){ tol=0; memset(head,-1,sizeof head); src=1,des=n,n; int vsize=vec.size(); for(int i=0;i<vsize;i++){ if(vec[i].cap<=dis0) adde(vec[i].u,vec[i].v,1); } } void solve(){ int l=minr,r=maxr; while(l<r){ int mid=(l+r)/2; build(mid); if(sap()>=num) r=mid; else l=mid+1; } printf("%d\n",r); } int main(){ while(scanf("%d%d%d",&n,&m,&num)!=EOF){ input(); solve(); } return 0; }
POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流),布布扣,bubuko.com
POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
标签:des style http color os io strong for
原文地址:http://blog.csdn.net/a1061747415/article/details/38406055