poj 2455 最大流+二分
阿新 • • 發佈:2019-01-24
一開始以為用矩陣 d[i][j] 可以節省時間和效率的呢,不過後來考慮到那樣可能會把邊搞的少了許多!!導致WA了n次。。。。
/* 題目描述: 題意:FJ有N塊地,這些地之間有P條雙向路,每條路的都有固定的長度l。 現在要你找出從第1塊地到第n塊地的T條不同路徑, 每條路徑上的路不能與先前的路徑重複,問這些路徑中的最長路的最小是多少。 */ #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define M 4100 const int inf=1<<30; int gap[M],dis[M],pre[M],cur[M]; int NE,NV,sink,source,d[402][402]; int head[M],n,p,ans; struct Node { int u,v,c,pos,next; } E[999999],Edge[999999]; #define FF(i,NV) for(int i=0;i<NV;i++) int sap(int s,int t) { //memset(pre,-1,sizeof(pre)); memset(dis,0,sizeof(int)*(NV+1)); memset(gap,0,sizeof(int)*(NV+1)); FF(i,NV) cur[i] = head[i]; int u = pre[s] = s,maxflow = 0,aug =inf; gap[0] = NV; while(dis[s] < NV) { loop: for(int &i = cur[u]; i != -1; i = E[i].next) { int v = E[i].pos; if(E[i].c && dis[u] == dis[v] + 1) { aug=min(aug,E[i].c); pre[v] = u; u = v; if(v == t) { maxflow += aug; for(u = pre[u]; v != s; v = u,u = pre[u]) { E[cur[u]].c -= aug; E[cur[u]^1].c += aug; } aug = 1<<29; } goto loop; } } int mindis = NV; for(int i = head[u]; i != -1 ; i = E[i].next) { int v = E[i].pos; if(E[i].c && mindis > dis[v]) { cur[u] = i; mindis = dis[v]; } } if( (--gap[dis[u]]) == 0)break; gap[ dis[u] = mindis+1 ] ++; u = pre[u]; } return maxflow; } void addEdge(int u,int v,int c ) { E[NE].c = c; E[NE].pos = v; E[NE].next = head[u]; head[u] = NE++; E[NE].c = 0; E[NE].pos = u; E[NE].next = head[v]; head[v] = NE++; } int ok(int mid,int t) { int i,j; NE=0; memset(head,-1,sizeof(int)*(NV+1)); addEdge(source,1,t); for(i=1; i<=p; i++) { if(Edge[i].c<=mid) { addEdge(Edge[i].u,Edge[i].v,1); addEdge(Edge[i].v,Edge[i].u,1); } } addEdge(n,sink,t); if(sap(source,sink)>=t) return 1; return 0; } int main() { int i,j,a,b,c,t; while(scanf("%d%d%d",&n,&p,&t)!=EOF) { source=0; sink=n+1; NV=sink+1; int l=inf,r=1; for(i=1; i<=p; i++) { scanf("%d%d%d",&a,&b,&c); Edge[i].u=a; Edge[i].v=b; Edge[i].c=c; r=max(c,r); l=min(l,c); } int res=1; while(l<=r) { int mid=(l+r)>>1; if(ok(mid,t)) { r=mid-1; res=mid; } else l=mid+1; } printf("%d\n",res); } return 0; } /* 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 */