Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3536 | Accepted: 1069 |
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
这道题的陷阱还是不少的
首先是二分答案,注意二分答案的格式,最后输出的答案是L,而不是MID,注意!!!
再者,注意重边啊!!!!因为题目大意是说只能走一次一条边,却没有说只能一次走一个点,所以的话,就是把存在的边二分答案的时候都放进数组中,进行SAP,即可得到答案。
WA了很多次,我还是太弱了。
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
const int V=210,E=400100;
struct NODE
{
int u,v,w;
NODE(int uu,int vv,int ww):u(uu),v(vv),w(ww) {}
};
vector<NODE> q;
struct edge
{
int aim,cap;
edge *next,*pair;
edge() {}
edge(int t,int c,edge *n):aim(t),cap(c),next(n) {}
void* operator new(unsigned,void* p)
{
return p;
}
}*e[V],Te[E+E],*Pe=Te;
int num[V],dis[V];
int n,p,tt,s,t;
int augment(int u,int augc)
{
if(u==t)return augc;
int d,tmp=n-1;
for(edge *i=e[u]; i; i=i->next)if(i->cap)
{
if(dis[u]==dis[i->aim]+1)
{
d=augment(i->aim,augc<i->cap?augc:i->cap);
i->cap-=d,i->pair->cap+=d;
if(d||dis[s]==n)return d;
}
if(dis[i->aim]<tmp)tmp=dis[i->aim];
}
if(!--num[dis[u]])dis[s]=n;
num[dis[u]=tmp+1]++;
return 0;
}
void init(int f)
{
int u,v,w;
memset(e,0,sizeof(e));
for(int i=0;i<q.size();i++)
{
NODE x=q[i];
u=x.u, v=x.v, w=x.w;
if(w<=f)
{
e[u]=new(Pe++)edge(v,1,e[u]);
e[v]=new(Pe++)edge(u,1,e[v]);
e[u]->pair=e[v];
e[v]->pair=e[u];
}
}
}
bool isap()
{
memset(dis,0,sizeof(dis));
memset(num,0,sizeof(num)),num[0]=n;
int flow=0;
s=1,t=n;
while(dis[s]<n) flow+=augment(s,0xfffffff);
if(flow>=tt) return true;
return false;
}
int main()
{
while(scanf("%d%d%d",&n,&p,&tt)!=EOF)
{
q.clear();
int front=10000000,top=-10000000;
for(int i=1;i<=p;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
q.push_back(NODE(x,y,c));
if(c>top) top=c;
if(c<front) front=c;
}
while(front<=top)
{
int mid=(front+top)/2;
init(mid);
if(isap()) top=mid-1;
else front=mid+1;
}
printf("%d/n",front);
}
return 0;
}