uva 11381(神奇的构图、最小费用最大流)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=29821

思路:首先拆点,每个字符对应的位置拆成i和i+len,然后源点和i连边,容量为1,花费为0,i+len与汇点连边,容量为1,花费为0,然后就是对于那些在P中的字符串连边,容量为1,花费为g[u][v],最后跑最小费最大流即可,然后答案就是len-flow,cost;

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")

  2 #include<iostream>

  3 #include<cstdio>

  4 #include<cstring>

  5 #include<climits>

  6 #include<cstdlib>

  7 #include<algorithm>

  8 #include<stack>

  9 #include<vector>

 10 #include<queue>

 11 #include<string>

 12 #include<cmath>

 13 #include<set>

 14 using namespace std;

 15 #define inf 1<<30

 16 #define INF 1LL<<60

 17 typedef long long ll;

 18 typedef pair<int,int>PP;

 19 #define MAXN 1111

 20 

 21 struct Edge{

 22     int v,cap,cost,next;

 23 }edge[MAXN*MAXN];

 24 

 25 int len,vs,vt,NE;

 26 int head[MAXN];

 27 

 28 void Insert(int u,int v,int cap,int cost)

 29 {

 30     edge[NE].v=v;

 31     edge[NE].cap=cap;

 32     edge[NE].cost=cost;

 33     edge[NE].next=head[u];

 34     head[u]=NE++;

 35 

 36     edge[NE].v=u;

 37     edge[NE].cap=0;

 38     edge[NE].cost=-cost;

 39     edge[NE].next=head[v];

 40     head[v]=NE++;

 41 }

 42 

 43 int pre[MAXN],cur[MAXN];

 44 bool mark[MAXN];

 45 int dist[MAXN];

 46 

 47 bool spfa(int vs,int vt)

 48 {

 49     memset(mark,false,sizeof(mark));

 50     fill(dist,dist+MAXN,inf);

 51     dist[vs]=0;

 52     queue<int>que;

 53     que.push(vs);

 54     while(!que.empty()){

 55         int u=que.front();

 56         que.pop();

 57         mark[u]=false;

 58         for(int i=head[u];i!=-1;i=edge[i].next){

 59             int v=edge[i].v,cost=edge[i].cost;

 60             if(edge[i].cap>0&&dist[u]+cost<dist[v]){

 61                 dist[v]=dist[u]+cost;

 62                 pre[v]=u;

 63                 cur[v]=i;

 64                 if(!mark[v]){

 65                     mark[v]=true;

 66                     que.push(v);

 67                 }

 68             }

 69         }

 70     }

 71     return dist[vt]<inf;

 72 }

 73 

 74 void MinCostFlow(int vs,int vt)

 75 {

 76     int flow=0,cost=0;

 77     while(spfa(vs,vt)){

 78         int aug=inf;

 79         for(int u=vt;u!=vs;u=pre[u]){

 80             aug=min(aug,edge[cur[u]].cap);

 81         }

 82         flow+=aug,cost+=dist[vt]*aug;

 83         for(int u=vt;u!=vs;u=pre[u]){

 84             edge[cur[u]].cap-=aug;

 85             edge[cur[u]^1].cap+=aug;

 86         }

 87     }

 88     printf("%d %d\n",len-flow,cost);

 89 }

 90 

 91 

 92 char str1[MAXN],str2[MAXN];

 93 int g[MAXN][MAXN];

 94 int main()

 95 {

 96     int _case;

 97     scanf("%d",&_case);

 98     while(_case--){

 99         scanf("%s",str1);

100         len=strlen(str1);

101         memset(g,0,sizeof(g));

102         for(int i=0;i<len-1;i++){

103             int u=str1[i]-'a',v=str1[i+1]-'a';

104             if(!g[u][v]){

105                 g[u][v]=(i+1)*(i+1);

106             }

107         }

108         scanf("%s",str2);

109         len=strlen(str2);

110         vs=0,vt=2*len+1;

111         NE=0;

112         memset(head,-1,sizeof(head));

113         for(int i=0;i<len;i++){

114             Insert(vs,i+1,1,0);

115             Insert(i+1+len,vt,1,0);

116             for(int j=i+1;j<len;j++){

117                 int u=str2[i]-'a',v=str2[j]-'a';

118                 if(g[u][v]){

119                     Insert(i+1,j+1+len,1,g[u][v]);

120                 }

121             }

122         }

123         MinCostFlow(vs,vt);

124     }

125     return 0;

126 }

127 

128 

129 

130 

131     
View Code

 

你可能感兴趣的:(uva)