[bzoj2055]80人环游世界[网络流,上下界网络流]
手动画了整张图,,算是搞懂了吧,,
1 #include <bits/stdc++.h> 2 3 #define INF 0x3f3f3f3f 4 5 using namespace std; 6 7 template<const int _n,const int _m> 8 struct Edge 9 { 10 struct Edge_base { int to,next,w,c; }e[_m]; int cnt,p[_n]; 11 Edge() { clear(); } 12 void clear() { cnt=1,memset(p,0,sizeof(p)); } 13 void insert(const int x,const int y,const int z,const int zz) 14 { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; e[cnt].c=zz; p[x]=cnt; return ; } 15 void link(const int x,const int y,const int z,const int zz) 16 { insert(x,y,z,zz); insert(y,x,0,-zz); } 17 int start(const int x) { return p[x]; } 18 Edge_base& operator[](const int x) { return e[x]; } 19 }; 20 21 int n,m,Dis[210],Cost; 22 int cur[210],SSS,TTT,SS,TT; 23 bool visited[210]; 24 Edge<210,510000>e; 25 26 bool Spfa(const int S) 27 { 28 int i,t,temp; 29 queue<int> Q; 30 memset(Dis,0x3f,sizeof(Dis)); 31 Dis[S]=0; 32 visited[S]=true; 33 Q.push(S); 34 while(!Q.empty()) 35 { 36 t=Q.front(),Q.pop(); 37 visited[t]=false; 38 for(i=e.start(t);i;i=e[i].next) 39 { 40 temp=e[i].to; 41 if(e[i].w && Dis[t]+e[i].c<Dis[temp]) 42 { 43 Dis[temp]=Dis[t]+e[i].c; 44 if(!visited[temp]) 45 { 46 visited[temp]=true; 47 Q.push(temp); 48 } 49 } 50 } 51 } 52 return Dis[TTT]!=0x3f3f3f3f; 53 } 54 55 int Dfs(const int S,const int bk) 56 { 57 if(S==TTT)return bk; 58 visited[S]=true; 59 int rest=bk; 60 for(int &i=cur[S];i;i=e[i].next) 61 { 62 if(!visited[e[i].to] && Dis[S]+e[i].c==Dis[e[i].to] && e[i].w) 63 { 64 int flow=Dfs(e[i].to,min(rest,e[i].w)); 65 Cost+=flow*e[i].c; 66 e[i].w-=flow; 67 e[i^1].w+=flow; 68 if((rest-=flow)<=0)break; 69 } 70 } 71 if(bk==rest)Dis[S]=0x3f3f3f3f; 72 visited[S]=false; 73 return bk-rest; 74 } 75 76 int Zkw() 77 { 78 int Flow=0; 79 while(Spfa(SSS)) 80 { 81 memcpy(cur,e.p,sizeof(cur)); 82 Flow+=Dfs(SSS,0x3f3f3f3f); 83 } 84 return Cost; 85 } 86 87 int main() 88 { 89 int i,j,a,x; 90 91 scanf("%d%d",&n,&m); 92 93 SS=n<<1|1,TT=SS+1,SSS=TT+1,TTT=SSS+1; 94 for(i=1;i<=n;++i) 95 { 96 scanf("%d",&a); 97 e.link(SSS,i+n,a,0); 98 e.link(i,TTT,a,0); 99 e.link(i+n,TT,INF,0); 100 e.link(SS,i,INF,0); 101 } 102 103 for(i=1;i<=n;++i)for(j=i+1;j<=n;++j) 104 { 105 scanf("%d",&x); 106 if(x==-1)continue; 107 e.link(i+n,j,INF,x); 108 } 109 110 e.link(TT,SS,m,0); 111 112 printf("%d\n",Zkw()); 113 return 0; 114 }