这几道都是上周llj讲的题,题解也写得十分好了,所以直接贴了几个链接和代码。
//Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<queue> #include<cmath> #include<ctime> #include<map> #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 N=200007,inf=0x7fffffff; typedef long long LL; using namespace std; int n,m,s,t,num,D[107][107],id[107][107],ans; map<int,int>mp; template<typename T> void read(T &x) { T f=1; x=0; char ch=getchar(); while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar(); if(ch==‘-‘) f=-1,ch=getchar(); for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f; } struct edge { int u,v,fl,cap,nx; edge(){} edge(int u,int v,int fl,int cap,int nx):u(u),v(v),fl(fl),cap(cap),nx(nx){} }e[N]; int fir[N],cur[N],ecnt=1,p[N]; void add(int u,int v,int cap) { e[++ecnt]=edge(u,v,0,cap,fir[u]); fir[u]=ecnt; e[++ecnt]=edge(v,u,0,0,fir[v]); fir[v]=ecnt; } int calc(int s,int t) { int fl=inf; for(int i=t;i!=s;i=e[p[i]].u) fl=min(fl,e[p[i]].cap-e[p[i]].fl); for(int i=t;i!=s;i=e[p[i]].u) e[p[i]].fl+=fl,e[p[i]^1].fl-=fl; return fl; } int d[N],c[N]; queue<int>que; void bfs(int s,int t) { for(int i=1;i<=n;i++) cur[i]=fir[i],d[i]=n,c[i]=0; que.push(t); d[t]=0; while(!que.empty()) { int x=que.front(); que.pop(); for(int i=fir[x];i;i=e[i].nx) if(e[i].cap==0) { int y=e[i].v; if(d[y]==n) { d[y]=d[x]+1; que.push(y); } } } } int ISAP(int s,int t) { int res=0; bfs(s,t); for(int i=1;i<=n;i++) c[d[i]]++; for(int x=s;d[x]<n;) { if(x==t) { res+=calc(s,t); x=s; } int ok=0; for(int &i=cur[x];i;i=e[i].nx) if(e[i].fl<e[i].cap&&d[e[i].v]+1==d[x]) { p[x=e[i].v]=i; ok=1; break; } if(!ok) { int M=n; cur[x]=fir[x]; for(int i=fir[x];i;i=e[i].nx) if(e[i].cap>e[i].fl) { M=min(M,d[e[i].v]+1); } if(!(--c[d[x]])) break; c[d[x]=M]++; if(x!=s) x=e[p[x]].u; } } return res; } int main() { read(n); read(m); s=++num; t=++num; num+=n; For(i,1,n) { int col; read(col); if(!mp[col]) { mp[col]=++num; add(num,t,m*col*col); } add(i+2,mp[col],inf); add(i+2,t,col); } For(i,1,n) For(j,i,n) { read(D[i][j]); id[i][j]=++num; if(D[i][j]>=0) { add(s,num,D[i][j]); ans+=D[i][j]; } else add(num,t,-D[i][j]); add(num,i+2,inf); add(num,j+2,inf); } For(i,1,n) For(j,i,n) if(i!=j) { add(id[i][j],id[i+1][j],inf); add(id[i][j],id[i][j-1],inf); } n=num; ans-=ISAP(s,t); printf("%d\n",ans); return 0; }
原文地址:https://www.cnblogs.com/Achenchen/p/8604806.html
时间: 2024-10-08 20:08:16