zoukankan      html  css  js  c++  java
  • hdu-5772 String problem(最大权闭合子图)

    题目链接:

    String problem

    Time Limit: 2000/1000 MS (Java/Others)   

     Memory Limit: 65536/65536 K (Java/Others)



    Problem Description
    This is a simple problem about string. Now a string S contains only ‘0’-‘9’. ?? wants to select a subsequence from this string. And makes this subsequence score maximum. The subsequence’s score is calculated as follows:
    Score= Value – Total_Cost
    The calculation of the Cost is as follows:
    If the number of characters x in the subsequence is kx, And the two coefficients are ax,bx,The cost of character x calculated as follows:


    {cost[x]=0,kx=0cost[x]=ax(kx1)+bx,kx0

    TotalCost=i=09cost[i]

    The calculation of the Value is as follows:

    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]];
    }
    }

    id[i] is the position of the subsequence’s ith character in the original string,for example,if the original string is “13579”,and the subsubquence is “159”,then the array id ={1,3,5}. The w is a weight matrix.
     
    Input
    The first line contains an integer T, denoting the number of the test cases.
    For each test case, the first line contains one integers n, the length of a string.
    Next line contains the string S.
    Next ten lines,each line contains ai,bi,denote the char i’s(0-9) coefficients
    Next is a n*n matrix w.
    Limits:
    T<=20,
    0<=n<=100
    0<=ai<=bi<=1000
    0<=w[i][j]<=50

     
    Output
    Each test output one line “Case #x: y” , where x is the case number ,staring from 1. y is the Maximum score.
     
    Sample Input
    1
    3
    135
    1 2
    1 2
    1 2
    1 2
    1 2
    1 2
    1 2
    1 2
    1 2
    1 2
    0 0 3
    1 0 0
    4 0 0
     
    Sample Output
    Case #1: 3
     
    题意:
     
    求这个式子的最大值;
     
    思路:
     
    这个也是最大权闭合子图的应用,如果要选第i行第j个w[i][j]那么一定要选序列中第i个和第j个,选了第i个和第j个那么一定要选相应的数字了;
    题解是这样给的:
    第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分)
    第二类:原串中的n个点每个点拆出一个点,第i个点权值为 –a[s[i]] (表示要花费)
    第三类:对于10种字符拆出10个点,每个点的权值为  -(b[x]-a[x])
     
    然后就是建图跑最大流的算法了;
     
    AC代码:
    #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('
    ');
    }
     
    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
    ",++Case,sum);
        }
        return 0;
    }
    

      

  • 相关阅读:
    《阿里感悟》- 技术人员的职业规划
    DIV Vue-cil脚手架
    Django PIL模块(生成随机验证码)
    Django auth模块(用户认证组件)
    Django 数据处理流程
    Django 中间件
    Django ORM (2)
    Django组件——Form
    Django orm
    Django urls
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5779429.html
Copyright © 2011-2022 走看看