这道题用的network flow。。
好高大上的网络流。
好高大上的网络流。
其实是可以写双向dp的 只是我没反应过来 当时就只写了网络流
网络流版
#include<cstring>
#include<cstdio>
#include<queue>
#define cle(a,b) memset(a,b,sizeof(a))
#define loop(i,j,k) for(int i=j;i<=k;i++)
#define MAXN (15)
using namespace std;
int n,ans;
int map[MAXN][MAXN];
struct edge{
int u,v,w,ll,next;
}e[MAXN*MAXN*8];
int cnt=-1;
int head[MAXN*MAXN*2];
void adde(int u,int v,int w,int ll) {
e[++cnt].v=v;
e[cnt].u=u;
e[cnt].w=w;
e[cnt].ll=ll;
e[cnt].next=head[u];
head[u]=cnt;
e[++cnt].v=u;
e[cnt].u=v;
e[cnt].w=-w;
e[cnt].ll=0;
e[cnt].next=head[v];
head[v]=cnt;
}
void readdata(){
scanf("%d",&n);
int u,v,w;
while(1){
scanf("%d",&u);
if(!u)
break;
scanf("%d%d",&v,&w);
map[u][v]=w;
}
}
int change(int x,int y){
return (x-1)*n+y;
}
void ready(){
cle(head,-1);
int now;
loop(i,1,n){
loop(j,1,n){
now=change(i,j);
if(map[i][j])
adde(now,now+n*n,map[i][j],1);
adde(now,now+n*n,0,100);
}
}
loop(i,1,n-1){
loop(j,1,n-1){
now=change(i,j);
adde(now+n*n,now+n,0,100);
adde(now+n*n,now+1,0,100);
}
}
loop(j,1,n-1){
now=change(n,j);
adde(now+n*n,now+1,0,100);
now=change(j,n);
adde(now+n*n,now+n,0,100);
}
adde(0,1,0,2);
adde(n*n*2,n*n*2+1,0,2);
}
int dis[MAXN*MAXN*2];
int inq[MAXN*MAXN*2];
int fa[MAXN*MAXN*2];
queue<int>q;
bool re;
bool spfa(){
cle(dis,-0x3f);
cle(inq,0);
cle(fa,-1);
re=false;
dis[0]=0;
q.push(0);
inq[0]=1;
int cs;
while(!q.empty()){
cs=q.front();
q.pop();
inq[cs]=0;
for(int i=head[cs];i!=-1;i=e[i].next){
if(cs==7){
int hehe=1;
}
if(e[i].ll==0)
continue;
int v=e[i].v;
if(dis[v]<dis[cs]+e[i].w){
dis[v]=dis[cs]+e[i].w;
fa[v]=i;
if(v==1+2*n*n)
re=true;
if(!inq[v]){
inq[v]=1;
q.push(v);
}
}
}
}
return re;
}
void solve(){
int minll;
int now;
while(1){
minll=0x3f3f3f3f;
if(spfa()){
now=2*n*n+1;
while(now!=0){
now=fa[now];
minll=min(minll,e[now].ll);
now=e[now].u;
}
now=2*n*n+1;
while(now!=0){
now=fa[now];
e[now].ll-=minll;
e[now^1].ll+=minll;
now=e[now].u;
}
ans+=minll*dis[2*n*n+1];
}
else break;
}
}
void print(){
printf("%d\n",ans);
}
int main(){
readdata();
ready();
solve();
print();
}
dp版不想写了,,