woc我真的想打人了,inf值如果不调到最大就tle是什么鬼?????我整整调了将近一个小时啊淦!
。。
连边的话,看amber的论文就好了,然后形成最大权封闭子图,s向正权点连边,负权点向t连边,容量都为权值,可以证明一个方案和一个割一一对应。
/**************************************************************
Problem: 1497
User: NamlessYang
Language: C++
Result: Accepted
Time:652 ms
Memory:7856 kb
****************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define T n+m+1
#define inf 0x7fffffff
using namespace std;
int n,m;
const int N=5e5+5;
int head[60001],next[N],go[N],val[N];
int h[60005],tot=1,q[60001],ans=0;
void ins(int x,int y,int z)
{
go[++tot]=y;
val[tot]=z;
next[tot]=head[x];
head[x]=tot;
go[++tot]=x;
next[tot]=head[y];
head[y]=tot;
}
bool bfs()
{
int now,t=0,w=1,p,i;
memset(h,-1,sizeof(h));
q[t]=h[0]=0;
while(t<w)
{
now=q[t];t++;
i=head[now];
while(i)
{
if(val[i]&&h[go[i]]<0)
{
q[w++]=go[i];
h[go[i]]=h[now]+1;
}
i=next[i];
}
}
if(h[n+m+1]==-1)return 0;
return 1;
}
int dfs(int x,int f)
{
if(x==n+m+1)return f;
int i=head[x];
int w,used=0;
while(i)
{
if(val[i]&&h[go[i]]==h[x]+1)
{
w=f-used;
w=dfs(go[i],min(w,val[i]));
val[i]-=w;
val[i^1]+=w;
used+=w;
if(used==f)return f;
}
i=next[i];
}
if(!used)h[x]=-1;
return used;
}
void dinic()
{
while(bfs())ans+=dfs(0,inf);
}
int main()
{
int sum=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
ins(0,i,a);
}
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
ins(a,n+i,inf);
ins(b,n+i,inf);
ins(n+i,n+m+1,c);
sum+=c;
}
dinic();
printf("%d",sum-ans);
return 0;
}