zoukankan      html  css  js  c++  java
  • HDU

    Hold Your Hand

    Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
    Total Submission(s): 169    Accepted Submission(s): 38

    Problem Description
    She walks in beauty, like the night of cloudless climes and starry skies. And all that's best of dark and bright, meet in her aspect and her eyes. Thus mellow'd to that tender light, which heaven to gaudy day denies. Fang Fang says she is afraid of dark.

    ``Never fear, I will hold your hand," I reply.

    Fang Fang says she hates some 8-digit binary numbers.
    I ask Cupid for help. Cupid can sell me some supernatural powers.
    Some of them can eliminate all 8-digit binary numbers in the world with a certain prefix, and some of them can eliminate all 8-dight binary numbers with a certain suffix.

    ``..., but you must offer your IQ in exchange for them."

    ``You have my permission", I say. True, I should minimize my damage, but maybe you can help me.
     
    Input
    The input contains several test cases. The first line of the input is a single integer t (t10) which is the number of test cases.

    Then t test cases follow.
    Each test case contains several lines.
    The first line contains the integer n (1n256) and m (1m500).
    Here, n corresponds to the number of 8-digit binary numbers which Fang Fang hates, and m corresponds to the number of supernatural powers.
    The second line contains n integer numbers a1,a2,,an where 0a1,,an255, which are 8-digit binary numbers written by decimal representation.
    The following m lines describe the supernatural powers one per line in two formats.
    P s w: you can eliminate all 8-digit binary numbers by prefixing the string s, with w (1w1000) units of IQ.
    S s w: you can eliminate all 8-digit binary numbers by suffixing the string s, with w (1w1000) units of IQ.
     
    Output
    For each test case, you should output the minimum cost of IQ as a unit, or ``-1" if Cupid could not help me.
     
    Sample Input
    1
    8 7
    0 1 2 3 4 5 6 7
    P 000001 1
    P 0000000 1
    S 10 1
    S 11 1
    S 00 1
    S 01 1
    P 0000001 3
     
     
    Sample Output
    Case #1: 4
     

    题意转化一下就是要割断所有的8位二进制。

    将前缀插入以S为根的字典树,后缀插入以T为根的字典树。val保存最小的w。

    一个前缀对应着割断所有包含这个前缀的二进制,后缀类似。

    然后把两颗树的对应叶子结点相连跑最小割。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int sigma_size = 2,maxnds = (256*8*2+56)*2;
    int S,T;
    
    struct Edge
    {
        int v,cap,nxt;
    };
    #define PB push_back
    vector<Edge> edges;
    int head[maxnds];
    inline void AddEdge(int u,int v,int c)
    {
        edges.PB({v,c,head[u]});
        head[u] = edges.size()-1;
        edges.PB({u,0,head[v]});
        head[v] = edges.size()-1;
    }
    
    bool vis[maxnds];
    int lv[maxnds],cur[maxnds];
    bool bfs()
    {
        memset(vis,0,sizeof(vis));
        queue<int> q; q.push(S); lv[S] = 1;
        vis[S] = true;
        while(q.size()){
            int u = q.front(); q.pop();
            for(int i = head[u]; ~i; i = edges[i].nxt){
                Edge &e = edges[i];
                if(!vis[e.v] && e.cap>0){
                    vis[e.v] = true;
                    lv[e.v] = lv[u]+1;
                    q.push(e.v);
                }
            }
        }
        return vis[T];
    }
    
    int aug(int u,int a)
    {
        if(u == T||!a) return a;
        int flow = 0,f;
        for(int &i = cur[u]; ~i; i = edges[i].nxt){
            Edge &e = edges[i];
            if(lv[e.v] == lv[u]+1 && (f=aug(e.v,min(a,e.cap)))>0){
                e.cap -= f; edges[i^1].cap += f;
                flow += f; a -= f;
                if(!a) break;
            }
        }
        return flow;
    }
    
    int MaxFlow()
    {
        int flow = 0;
        while(bfs()){
            memcpy(cur,head,sizeof(head));
            flow += aug(S,INF);
            if(flow >= INF) break;
        }
        return flow;
    }
    
    struct Node
    {
        int ch[sigma_size],val;
        void init(){}
    }nd[maxnds];
    const int nil = 0;
    int cnt;
    
    inline int newNode()
    {
        int i = ++cnt;
        memset(nd[i].ch,nil,sizeof(nd[i].ch));
        nd[i].val = INF;
        head[i] = -1;
        return i;
    }
    
    
    int add(int rt,char *s,int v = INF)
    {
        int u = rt;
        for(int i = 0; s[i]; i++){
            int c = s[i]-'0';
            if(!nd[u].ch[c]){
                nd[u].ch[c] = newNode();
            }
            u = nd[u].ch[c];
        }
        nd[u].val = min(nd[u].val,v);
        return u;
    }
    
    
    bool flag;
    void dfs(int u)
    {
        for(int i = 0; i < sigma_size; i++){
            int v = nd[u].ch[i];
            if(v){
                int w = nd[v].val;
                if(flag){
                    AddEdge(u,v,w);
                }else {
                    AddEdge(v,u,w);
                }
                dfs(v);
            }
        }
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
    
        char s[10];
        int x[256+6];
        int Test; scanf("%d",&Test);
        for(int kas = 1; kas<= Test; kas++){
            edges.clear();
            cnt = 0;
            S = newNode(); T = newNode();
    
            int n,m; scanf("%d%d",&n,&m);
            for(int i = 0; i < n; i++){
                scanf("%d",x+i);
            }
    
            while(m--){
                char ch[2];
                int w; scanf("%s%s%d",ch,s,&w);
                if(*ch=='P'){
                    add(S,s,w);
                }else {
                    reverse(s,s+strlen(s));
                    add(T,s,w);
                }
            }
            s[8] = '';
            for(int i = 0; i < n; i++){
                int t = x[i];
                for(int j = 0; j < 8; j++){
                    s[j] = (t&1)+'0';
                    t>>=1;
                }
                int v = add(T,s);
                reverse(s,s+8);
                AddEdge(add(S,s),v,INF);
            }
            flag = true;
            dfs(S);
            flag = false;
            dfs(T);
            printf("Case #%d: ",kas);
            int flow = MaxFlow();
            if(flow >= INF){
                puts("-1");
            }else printf("%d
    ",flow);
        }
        return 0;
    }
  • 相关阅读:
    微软Silverlight团队关于PDC会议发表官方补充声明(风云翻译版)
    《银光志Silverlight 3.0开发详解与最佳实践》发行第三版总销量过万册
    Silverlight医学PACS诊断分析管理系统【案例分享】
    微软PDC10与最后的恐慌者
    风云的银光志Silverlight4.0教程之与学会使用Frame控件
    WPF案例之生产线控制器管理系统
    WindowsPhone7 经典3D游戏《刺客信条》评测
    Silverlight4开发的炫酷企业网站整站(运行大量特效)
    微软Windows Phone7超越Android、iOS的五大优势
    as3 滤镜学习笔记
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4837012.html
Copyright © 2011-2022 走看看