题目链接:
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Value=0;
for(int i=1;i<=length(substr);++i){
for(int j=1;j<=length(substr);++j){
if(i!=j)
Value+=w[id[i]][id[j]];
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#include <map>
using namespace std;
#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar());
for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + ‘0‘);
putchar(‘\n‘);
}
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=1e4+120;
const int maxn=1e4+220;
const double eps=1e-12;
int a[12],b[12],c[110],w[110][110];
char str[110];
struct Edge
{
int from,to,cap,flow;
};
vector<int>G[maxn];
vector<Edge>edges;
int cur[maxn],d[maxn],s,t,n,m,sum;
bool vis[maxn];
inline void add_edge(int from,int to,int cap)
{
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool bfs()
{
mst(vis,0);
queue<int>qu;
qu.push(s);
d[s]=0;vis[s]=1;
while(!qu.empty())
{
int fr=qu.front();qu.pop();
for(int i=0;i<G[fr].size();i++)
{
Edge& e=edges[G[fr][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to]=1;
d[e.to]=d[fr]+1;
qu.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x,int a)
{
if(x==t||a==0)return a;
int flow=0,f;
for(int& i=cur[x];i<G[x].size();i++)
{
Edge& e=edges[G[x][i]];
if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
int Dinic()//跑最大流Dinic算最小割
{
int flow=0;
while(bfs())
{
mst(cur,0);
flow+=dfs(s,inf);
}
return flow;
}
inline void Init()//建图
{
sum=0;s=0;
int tot=n+10;
For(i,1,n)
{
For(j,i+1,n)
{
tot++;
add_edge(tot,i,inf);
add_edge(tot,j,inf);
add_edge(s,tot,w[i][j]+w[j][i]);
sum+=w[i][j]+w[j][i];
}
}
tot++;t=tot;
For(i,1,n)
{
add_edge(i,c[i]+n+1,inf);
add_edge(i,t,a[c[i]]);
}
For(i,0,9)
{
add_edge(i+n+1,t,b[i]-a[i]);
}
}
int main()
{
int t,Case=0;
read(t);
while(t--)
{
edges.clear();
For(i,0,maxn-2)G[i].clear();
read(n);
scanf("%s",str);
For(i,0,n-1)c[i+1]=str[i]-‘0‘;
For(i,0,9)read(a[i]),read(b[i]);
For(i,1,n)For(j,1,n)read(w[i][j]);
Init();
sum-=Dinic();
printf("Case #%d: %d\n",++Case,sum);
}
return 0;
}
hdu-5772 String problem(最大权闭合子图)
原文:http://www.cnblogs.com/zhangchengc919/p/5779429.html