zoukankan      html  css  js  c++  java
  • 杂七杂八的模板

    最小表示法(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
    ",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
    ");
    		else printf("Nacci
    ");
    		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
    ",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("
    ");
    		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
    ",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
    ",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
    ",ef(x));
    		}
    		printf("
    ");
    	}
    	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
    ",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
    ",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
    ",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
    ",zl(n+1,n+1));
    	return 0;
    }
    

      

  • 相关阅读:
    PowerDesigner11.0的SQL生成表,写列描述出错
    centos中crontab(计时器)用法详解
    5.14
    4.13
    5.15
    监听服务启动失败
    4.24
    Enjoy 4.26
    4.14
    export
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/8321823.html
Copyright © 2011-2022 走看看