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

来源:互联网 发布:於于同:无主之花 知乎 编辑:程序博客网 时间:2024/05/20 19:18

题目链接: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

 

0 0
原创粉丝点击