。。。第一个网络流的题目
牛淋雨什么的,建图,用模板之
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
long long F,P;
long long cowsum;
const int MAX=555;
long long tttt=(1<<31)-1;
const long long INF=tttt*tttt;
long long dis[MAX][MAX];
long long cownum[MAX];
long long sheld[MAX];
//SAP最大流模版
const long long MAXN=1111;//点数的最大值
const long long MAXM=222222;//边数的最大值
struct Node
{
long long from,to,next;
long long cap;
}edge[MAXM];
long long tol;
long long head[MAXN];
long long dep[MAXN];
long long gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
long long n;//n是总的点的个数,包括源点和汇点
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(long long u,long long v,long long w)
{
edge[tol].from=u;
edge[tol].to=v;
edge[tol].cap=w;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].from=v;
edge[tol].to=u;
edge[tol].cap=0;
edge[tol].next=head[v];
head[v]=tol++;
}
void BFS(long long start,long long end)
{
memset(dep,-1,sizeof(dep));
memset(gap,0,sizeof(gap));
gap[0]=1;
long long que[MAXN];
long long front,rear;
front=rear=0;
dep[end]=0;
que[rear++]=end;
while(front!=rear)
{
long long u=que[front++];
if(front==MAXN)front=0;
for(long long i=head[u];i!=-1;i=edge[i].next)
{
long long v=edge[i].to;
if(dep[v]!=-1)continue;
que[rear++]=v;
if(rear==MAXN)rear=0;
dep[v]=dep[u]+1;
++gap[dep[v]];
}
}
}
long long SAP(long long start,long long end)
{
long long res=0;
BFS(start,end);
long long cur[MAXN];
long long S[MAXN];
long long top=0;
memcpy(cur,head,sizeof(head));
long long u=start;
long long i;
while(dep[start]<n)
{
if(u==end)
{
long long temp=INF;
long long inser;
for(i=0;i<top;i++)
if(temp>edge[S[i]].cap)
{
temp=edge[S[i]].cap;
inser=i;
}
for(i=0;i<top;i++)
{
edge[S[i]].cap-=temp;
edge[S[i]^1].cap+=temp;
}
res+=temp;
top=inser;
u=edge[S[top]].from;
}
if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
break;
for(i=cur[u];i!=-1;i=edge[i].next)
if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
break;
if(i!=-1)
{
cur[u]=i;
S[top++]=i;
u=edge[i].to;
}
else
{
long long min=n;
for(i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].cap==0)continue;
if(min>dep[edge[i].to])
{
min=dep[edge[i].to];
cur[u]=i;
}
}
--gap[dep[u]];
dep[u]=min+1;
++gap[dep[u]];
if(u!=start)u=edge[S[--top]].from;
}
}
return res;
}
void input()
{
scanf("%lld%lld",&F,&P);
n=F*2+2;
for(long long i=1;i<=F;i++)
{
for(long long j=1;j<=F;j++)
{
dis[i][j]=INF;
}
dis[i][i]=0;
}
for(long long i=1;i<=F;i++)
{
long long a,b;scanf("%lld%lld",&a,&b);
cownum[i]=a;sheld[i]=b;
cowsum+=a;
}
for(long long i=1;i<=P;i++)
{
long long u,v,len;scanf("%lld%lld%lld",&u,&v,&len);
if(dis[u][v]>len)
{
dis[v][u]=dis[u][v]=len;
}
}
}
void floyd()
{
for(long long k=1;k<=F;k++)
{
for(long long i=1;i<=F;i++)
{
for(long long j=1;j<=F;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
}
void makemap(long long maxedge)
{
for(long long i=1;i<=F;i++)
{
for(long long j=1;j<=F;j++)
{
if(dis[i][j]<=maxedge)
{
addedge(i,j+F,INF);
}
}
}
for(long long i=1;i<=F;i++)
{
addedge(0,i,cownum[i]);
}
for(long long i=1;i<=F;i++)
{
addedge(i+F,2*F+1,sheld[i]);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("G:/1.txt","r",stdin);
freopen("G:/2.txt","w",stdout);
#endif
input();
floyd();
long long ans;
long long L=0,R=0,mid=0;
for(long long i=1;i<=F;i++)
{
for(long long j=1;j<=F;j++)
{
if(dis[i][j]<INF)
R=max(R,dis[i][j]);
}
}
R+=10;mid=(L+R)>>1;
long long ANS=-1;
while(L<R)
{
init();
makemap(mid);
ans=SAP(0,2*F+1);
if(ans>=cowsum)
{
ANS=R=mid;
mid=(L+R)>>1;
}
else
{
L=mid+1;
mid=(L+R)>>1;
}
}
printf("%lld\n",ANS);
}