杂七杂八的模板
最小表示法(poj1509)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=1e5+7;
int T,n;
char s[maxn];
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
int solve() {
int i=0,j=1,k=0,t;
while(i<n&&j<n&&k<n) {
t=s[(i+k)%n]-s[(j+k)%n];
if(t==0) k++;
else {
if(t>0) i+=k+1;
else j+=k+1;
if(i==j) j++;
k=0;
}
}
return min(i,j);
}
int main() {
read(T);
while(T--) {
scanf("%s",s);
n=strlen(s);
printf("%d\n",solve()+1);
}
return 0;
}
sg函数(hdu1848)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=1000+7;
int n[3],f[maxn],sg[maxn],ans;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
bool vis[maxn];
int get_sg(int x) {
memset(vis,0,sizeof(vis));
for(int i=1;f[i]<=x;++i) vis[sg[x-f[i]]]=1;
for(int i=0;;++i) if(!vis[i]) return i;
}
int main() {
f[0]=f[1]=1;
for(int i=2;i<=1000;++i) {
f[i]=f[i-1]+f[i-2];
if(f[i]>1000) break;
}
memset(sg,-1,sizeof(sg));sg[0]=0;
for(int i=1;i<=1000;++i) sg[i]=get_sg(i);
read(n[0]); read(n[1]); read(n[2]);
while(n[0]||n[1]||n[2]) {
ans=sg[n[0]]^sg[n[1]]^sg[n[2]];
if(ans) printf("Fibo\n");
else printf("Nacci\n");
read(n[0]); read(n[1]); read(n[2]);
}
return 0;
}
树hash(bzoj4337)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=50+7;
const ll base=1031,bs=1234,bse=5107043,mod=1000000007;
int n,m,fa[maxn],ans;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
int fir[maxn],nxt[2*maxn],to[2*maxn],e=0;
void add(int x,int y) {
to[++e]=y; nxt[e]=fir[x]; fir[x]=e;
to[++e]=x; nxt[e]=fir[y]; fir[y]=e;
}
ll hsh[maxn],now[maxn],zz[maxn],t,fz[maxn],tt;
bool vis[maxn];
void get_hash(int pos) {
vis[pos]=1;
for(int y=fir[pos];y;y=nxt[y])
if(!vis[to[y]]) get_hash(to[y]);
t=0;
for(int y=fir[pos];y;y=nxt[y])
if(!vis[to[y]]) zz[++t]=now[to[y]];
vis[pos]=0;
if(!t) {
now[pos]=bs;
return;
}
sort(zz+1,zz+t+1);
for(int i=1;i<=t;++i) {
now[pos]^=zz[i];
now[pos]=now[pos]*base%mod;
}
}
int main() {
read(m);
for(int i=1;i<=m;++i) {
read(n);
memset(fir,0,sizeof(fir)); e=0; tt=0;
for(int j=1;j<=n;++j) {
read(fa[j]);
if(fa[j]) add(fa[j],j);
}
for(int j=1;j<=n;++j) {
memset(now,0,sizeof(now));
memset(vis,0,sizeof(vis));
get_hash(j); fz[j]=now[j];
}
sort(fz+1,fz+n+1);
for(int j=1;j<=n;++j) hsh[i]=(hsh[i]^fz[j])*bse%mod;
for(int j=i;j;--j) if(hsh[j]==hsh[i]) ans=j;
printf("%d\n",ans);
}
return 0;
}
/*
4
4 0 1 1 2
4 2 0 2 3
4 0 1 1 1
4 0 1 2 3
*/
笛卡尔树(poj1785)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=50000+7;
int n,p[maxn],pr[maxn];
char c,s[maxn][117];
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
int ui;
bool cmp(int x,int y) {
return strcmp(s[x],s[y])<=0;
}
int son[maxn][2],root;
int zz[maxn],t,last;
void print_ans(int pos) {
printf("(");
if(son[pos][0]) print_ans(son[pos][0]);
printf("%s/%d",s[pos],pr[pos]);
if(son[pos][1]) print_ans(son[pos][1]);
printf(")");
}
void solve() {
t=0;
memset(son,0,sizeof(son)); root=0;
for(int i=1;i<=n;++i) {
last=0;
while(t&&pr[zz[t]]<pr[p[i]]) {
last=zz[t];
t--;
}
son[p[i]][0]=last;
if(!t) root=p[i];
else son[zz[t]][1]=p[i];
zz[++t]=p[i];
}
print_ans(root);
}
int main() {
scanf("%d",&n);
while(n) {
for(int i=1;i<=n;++i) {
p[i]=i;
scanf("%*[ ]%[^/]/%d",s[i],&pr[i]);
}
sort(p+1,p+n+1,cmp);
solve();printf("\n");
scanf("%d",&n);
}
return 0;
}
/*
7 a/7 b/6 c/5 d/4 e/3 f/2 g/1
7 a/1 b/2 c/3 d/4 e/5 f/6 g/7
7 a/3 b/6 c/4 d/7 e/2 f/5 g/1
0
*/
StoerWagner(poj2914)
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
const int maxn=500+7,maxm=maxn*maxn*2;
const ll INF=1e14;
int n,m;
char cc; ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
ll v[maxn],wage[maxn],num[maxn][maxn];
bool vis[maxn];
ll StoerWagner() {
ll rs=INF; int last,now=1;
For(i,1,n) v[i]=i;
Rep(nn,n,2) {
memset(vis,0,sizeof(vis));
memset(wage,0,sizeof(wage));
now=1;
For(i,1,nn-1) {
vis[now]=1; last=now; now=0;
For(j,1,nn) if(!vis[j]) {
wage[j]+=num[v[last]][v[j]];
if(now==0||wage[j]>wage[now]) now=j;
}
}
rs=min(rs,wage[now]);
For(i,1,nn) {
num[v[i]][v[last]]+=num[v[now]][v[i]];
num[v[last]][v[i]]+=num[v[now]][v[i]];
}
v[now]=v[nn];
}
return rs;
}
int main() {
int x,y,z;
while(scanf("%d%d",&n,&m)==2) {
memset(num,0,sizeof(num));
For(i,1,m) {
read(x); read(y); read(z);
++x; ++y;
num[x][y]+=z;
num[y][x]+=z;
}
printf("%lld\n",StoerWagner());
}
return 0;
}
最小割树(bzoj2229)
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
#define ll long long
const int maxn=150+7,maxm=6000+7;
const ll INF=1e14;
int Td,n,m,q,S,T,tot;
ll pp[maxn*maxn],ans[maxn][maxn];
char cc; ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
int a[maxn];
struct Node{
int x,y;ll flow,cap;
Node(){}
Node(int x,int y,ll cap):x(x),y(y),cap(cap){flow=0;}
}node[2*maxm];
int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,ll z) {
// printf("add: %d->%d %lld\n",x,y,z);
node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
}
int dis[maxn],zz[maxn];
bool bfs() {
int x,y,z,s=1,t=0;
memset(dis,-1,sizeof(dis));
zz[++t]=S; dis[S]=0;
while(s<=t) {
x=zz[s++]; if(x==T) return 1;
for(y=fir[x];y;y=nxt[y]) {
if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return 0;
}
ll dfs(int pos,ll maxf) {
if(pos==T||maxf==0) return maxf;
ll now,rs=0,z;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=dfs(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now;
node[y^1].flow-=now;
maxf-=now; rs+=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
ll Dinic() {
ll rs=0;
while(bfs()) {
memcpy(cur,fir,sizeof(fir));
rs+=dfs(S,INF);
}
return rs;
}
bool vis[maxn];
void dfs2(int pos) {
if(vis[pos]) return;//
vis[pos]=1; int y,z;
for(y=fir[pos];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap) continue;
z=node[y].y; dfs2(z);
}
}
void solve(int l,int r) {
if(l==r) return;
for(int i=2;i<=e;++i) node[i].flow=0;
S=a[l]; T=a[r];
ll x=Dinic();
memset(vis,0,sizeof(vis));
dfs2(S);
for(int i=1;i<=n;++i) if(vis[i])
for(int j=1;j<=n;++j) if(!vis[j])
ans[i][j]=ans[j][i]=min(ans[i][j],x);
for(int i=l;i<=r;++i) zz[i]=a[i];
int s=l-1,t=r+1;
for(int i=l;i<=r;++i) {
if(vis[zz[i]]) a[++s]=zz[i];
else a[--t]=zz[i];
}
solve(l,s); solve(t,r);
}
void clear() {
for(int i=1;i<=n;++i) a[i]=i; e=1;
memset(fir,0,sizeof(fir));
for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) ans[i][j]=INF;
}
int ef(ll x) {
int l=0,r=tot+1,mid;
pp[r]=INF;
while(l<r-1) {
mid=(l+r)>>1;
if(pp[mid]<=x) l=mid;
else r=mid;
}
return l;
}
int main() {
read(Td); int x,y,z;
while(Td--) {
read(n); read(m);
clear();
for(int i=1;i<=m;++i) {
read(x); read(y); read(z);
add(x,y,z);
add(y,x,z);
}
solve(1,n); tot=0;
for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) pp[++tot]=ans[i][j];
sort(pp+1,pp+tot+1);
read(q);
for(int i=1;i<=q;++i) {
read(x);
printf("%d\n",ef(x));
}
printf("\n");
}
return 0;
}
/*
2
5 0
1
0
5 0
1
0
*/
平面曼哈顿距离最小生成树
对于每个点,以它为中心把平面平均分成八个,每个面里面找一个距离它最近的点连一条边,然后做最小生成树即可。
原因:由最小生成树环切性质,如果形成一个环,最长的那条边是没有用的

如图,在东偏北区域内,|AB|<=|AC|,那么肯定有|AC|>=|BC|
所以AC是不优的。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
const int maxn=1e6+7,maxt=19,W=18;
const db INF=1e9;
int n,m,nowop=0;ll sumtot;
ll px[maxn],py[maxn],p[maxn];
char cc; ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
db pf(const db x){return x*x;}
const db eps=1e-12,PI=acos(-1),qr2=sqrt(2);
int dcmp(db x){return fabs(x)<eps? 0:(x>0? 1:-1);}
struct Node{
int id; db x,y;
}node[maxn];
bool cmp(const Node& a,const Node& b) {
return dcmp(a.x-b.x)==0? a.y < b.y : a.x < b.x;
}
struct Edge {
ll x,y,v;
}edge[2*maxn];
int tote;
bool cmp3(const Edge& a,const Edge& b) {
return a.v<b.v;
}
ll get_len(int x,int y) {
return abs(px[x]-px[y])+abs(py[x]-py[y]);
}
void insert(int x,int y) {
if(!x||!y||x==y) return ;
// printf("insert:%d->%d\n",x,y);
++tote;
edge[tote].x=x; edge[tote].y=y;
edge[tote].v=get_len(x,y);
}
int get_max(int x,int y) {
if((ll)x*y==0) return x+y;
if(!nowop) {
if(px[x]+py[x]>px[y]+py[y]) return x;
else return y;
}
if(nowop==1) {
if(px[x]-py[x]>px[y]-py[y]) return x;
else return y;
}
return 0;
}
int ql,qr,qx,maxnum[maxn];
void chge(int pos,int l,int r) {
maxnum[pos]=get_max(maxnum[pos],qx);
if(l==r) return;
int mid=(l+r)>>1;
if(ql<=mid) chge(pos<<1,l,mid);
else chge(pos<<1|1,mid+1,r);
}
int q(int pos,int l,int r) {
if(l>=ql&&r<=qr) return maxnum[pos];
int mid=(l+r)>>1;
if(qr<=mid) return q(pos<<1,l,mid);
if(ql>mid) return q(pos<<1|1,mid+1,r);
return get_max(q(pos<<1,l,mid),q(pos<<1|1,mid+1,r));
}
void clear(int pos,int l,int r) {
maxnum[pos]=0;
if(l==r) return;
int mid=(l+r)>>1;
clear(pos<<1,l,mid);
clear(pos<<1|1,mid+1,r);
}
void doit() {
For(i,1,n) node[i].id=i,p[i]=node[i].y;
sort(p+1,p+n+1);
sort(node+1,node+n+1,cmp);
For(i,1,n) {
int pos=lower_bound(p+1,p+n+1,node[i].y)-p;
ql=1; qr=pos;
insert(q(1,1,n),node[i].id);
ql=qr=pos; qx=node[i].id;
chge(1,1,n);
}
}
///////////////////////
int fir[maxn],nxt[2*maxn],to[2*maxn],e=0;ll v[2*maxn];
void add(int x,int y,ll z) {
// printf("add:%d->%d v:%lld\n",x,y,z);
to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;
to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z;
sumtot+=z;
}
int pp[maxn];
int find(int x){
return x==pp[x]? x:pp[x]=find(pp[x]);
}
void Kru() {
sort(edge+1,edge+tote+1,cmp3);
For(i,1,n) pp[i]=i;
int xx,yy,tot=0;
For(i,1,tote) {
xx=find(edge[i].x); yy=find(edge[i].y);
if(xx!=yy) {
add(edge[i].x,edge[i].y,edge[i].v);
++tot;
if(tot==n-1) break;
pp[xx]=yy;
}
}
}
int fa[maxn][maxt],dep[maxn];ll maxlen[maxn][maxt];
void dfs(int pos,int f) {
fa[pos][0]=f; dep[pos]=dep[f]+1;
For(i,1,W) {
fa[pos][i]=fa[fa[pos][i-1]][i-1];
maxlen[pos][i]=max(maxlen[pos][i-1],maxlen[fa[pos][i-1]][i-1]);
}
int y,z;
for(y=fir[pos];y;y=nxt[y]) {
if((z=to[y])==f) continue;
maxlen[z][0]=v[y];
dfs(z,pos);
}
}
ll Yth(int x,int y) {
if(fa[x][0]==y||fa[y][0]==x) return get_len(x,y);
ll rs=0;
if(dep[x]!=dep[y]) {
if(dep[x]<dep[y]) swap(x,y);
Rep(i,W,0) if(dep[fa[x][i]]>=dep[y])
rs=max(rs,maxlen[x][i]),x=fa[x][i];
}
if(x==y) return rs;
Rep(i,W,0) if(fa[x][i]!=fa[y][i]) {
rs=max(rs,maxlen[x][i]);
rs=max(rs,maxlen[y][i]);
x=fa[x][i]; y=fa[y][i];
}
rs=max(rs,maxlen[x][0]);
rs=max(rs,maxlen[y][0]);
return rs;
}
int main() {
read(n);
For(i,1,n) {read(px[i]); read(py[i]);}
////////////////////add edge
//West - South
For(i,1,n) {
node[i].x=px[i]-py[i];
node[i].y=py[i];
}
doit();
//South - West
clear(1,1,n);
For(i,1,n) {
node[i].x=px[i];
node[i].y=py[i]-px[i];
}
doit();
//West - North
clear(1,1,n); nowop=1;
For(i,1,n) {
node[i].x=px[i]+py[i];
node[i].y=py[i];
node[i].y=INF-node[i].y;
}
doit();
//North - West
clear(1,1,n); nowop=1;
For(i,1,n) {
node[i].x=px[i];
node[i].y=px[i]+py[i];
node[i].y=INF-node[i].y;
}
doit();
///////////////////
Kru();
dfs(1,0);
read(m); int x,y;
For(i,1,m) {
read(x); read(y);
printf("%lld\n",sumtot-Yth(x,y)+get_len(x,y));
}
return 0;
}
最大权闭合子图(bzoj3996)
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
const int maxn=1007*1007,INF=0x3f3f3f3f;
int n,S,T,D[maxn];
bool vis[maxn];
char cc; ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
struct Node{
int x,y,cap,flow;
Node(){}
Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;}
}node[2*maxn];
int fir[maxn],nxt[2*maxn],e=1;
void add(int x,int y,int z) {
node[++e]=Node(x,y,z);nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0);nxt[e]=fir[y];fir[y]=e;
}
int dis[maxn],zz[maxn];
bool BFS() {
memset(dis,-1,sizeof(dis));
int x,y,z,s=1,t=0;
zz[++t]=S; dis[S]=0;
while(s<=t) {
x=zz[s++]; if(x==T) return 1;
for(y=fir[x];y;y=nxt[y]) {
if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return 0;
}
int DFS(int pos,int maxf) {
if(pos==T||maxf==0) return maxf;
int rs=0,now,y,z;
for(y=fir[pos];y&&maxf;y=nxt[y]) {
if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=DFS(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now;
node[y^1].flow-=now;
rs+=now; maxf-=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
void Dinic() {
int rs=0;
while(BFS()) rs+=DFS(S,INF);
}
void dfs(int pos) {
if(vis[pos]) return;
vis[pos]=1;
for(int y=fir[pos];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap) continue;
dfs(node[y].y);
}
}
int main() {
read(n); int x,y,z;
S=n*n+n+1; T=S+1;
For(i,1,n*n) {
read(x);
add(S,i,x);
}
For(i,1,n) {
read(D[i]);
add(i+n*n,T,D[i]);
}
For(i,1,n) For(j,1,n) {
add((i-1)*n+j,i+n*n,INF);
if(i!=j) add((i-1)*n+j,j+n*n,INF);
}
Dinic();
dfs(S);
int ans=0;
for(y=fir[S];y;y=nxt[y]) {
if(vis[z=node[y].y]) ans+=node[y].cap;
}
For(i,1,n) if(vis[i+n*n]) ans-=D[i];
printf("%d",ans);
return 0;
}
朱刘算法
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(register int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
const int maxn=1000+7,maxm=1e6+7;
const ll INF=1e18,inf=1e14;
int n,m;
ll dis[maxn][maxn];
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
struct Edge{
int x,y; ll w;
Edge(){}
Edge(int x,int y,ll w):x(x),y(y),w(w){}
}edge[maxm];
int e;
ll d[maxn];
int pr[maxn],id[maxn],vis[maxn];
ll zl(int rt,int n) {
ll rs=0; int x,y,toth;
while(1) {
For(i,1,n) d[i]=INF; d[rt]=0;
For(i,1,e) {
x=edge[i].x; y=edge[i].y;
if(x!=y&&edge[i].w<d[y]) {
d[y]=edge[i].w;
pr[y]=x;
}
}
For(i,1,n) if(d[i]==INF) return -1;
For(i,1,n) vis[i]=id[i]=-1;
toth=0;
For(i,1,n) {
x=i; rs+=d[x];
while(id[x]==-1&&x!=rt&&vis[x]!=i) {
vis[x]=i; x=pr[x];
}
if(id[x]==-1&&x!=rt) {
id[x]=++toth;
for(y=pr[x];y!=x;y=pr[y]) id[y]=toth;
}
}
if(!toth) break;
For(i,1,n) if(id[i]==-1) id[i]=++toth;
For(i,1,e) {
x=edge[i].x; y=edge[i].y;
if(id[x]!=id[y]) edge[i].w-=d[y];
edge[i].x=id[x]; edge[i].y=id[y];
}
n=toth; rt=id[rt];
}
if(rs-inf>=inf) return -1;
return rs-inf;
}
int main() {
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
read(n); read(m);
For(i,1,n+1) For(j,1,n+1) dis[i][j]=INF;
int x,y; ll w;
For(i,1,m) {
read(x); read(y); read(w);
dis[x][y]=min(dis[x][y],w);
}
For(i,1,n) For(j,1,n) if(dis[i][j]!=INF)
edge[++e]=Edge(i,j,dis[i][j]);
For(i,1,n) edge[++e]=Edge(n+1,i,inf);
printf("%lld\n",zl(n+1,n+1));
return 0;
}
弱者就是会被欺负呀

浙公网安备 33010602011771号