zoukankan      html  css  js  c++  java
  • Word maker! 最大流dinic

    link:http://acm.upc.edu.cn/problem.php?id=2161

    这题的大题题意是给你N个多面体,每个多面体的每个面都有字母,然后告诉你几个单词,问你能拼出几个单词。

    从这道题意不难看出这每个多面体只能每次提供一个字母,也就是说每个多面体预期所带的字母之间所能提供的流量为1 ,不难看出是个二分图,当时用的DFS果断超时,然后想到二分匹配时觉得二分匹配不熟,写了个EK最大流也超市。。。后来回到宿舍敲了一个DINIC果断88ms啊!刚才写了个二分匹配还是超市,不过QC他们的二分过了不知道为什么。。。

    #include <stdio.h>
    #include <iostream>
    #include <queue>
    #include <string.h>
    #include <vector>
    #define maxn 1050
    using namespace std;
    int m,n;
    struct edge
    {
        int u,v,cap,flow;
    };
    vector<edge>edges;
    vector<edge>ed;
    vector<int>g[maxn],G[maxn];
     
    void addedge(int u,int v,int cap,int flow)
    {
        edges.push_back((edge){u,v,cap,flow});
        edges.push_back((edge){v,u,0,0});
        int m;
        m = edges.size();
        g[u].push_back(m-2);
        g[v].push_back(m-1);
    }
     
    void init(int n)
    {
        int i;
        for(i = 0;i <= n;i++)
        {
            g[i].clear();
        }
        edges.clear();
    }
    int vis[maxn],dis[maxn],cur[maxn];
    int bfs(int s,int t,int n)
    {
        memset(vis,0,sizeof(vis));
        queue<int>q;
        q.push(s);
        dis[s] = 0;
        vis[s] = 1;
     
        while(!q.empty())
        {
            int u,v;
            u = q.front();
            q.pop();
            for(int i = 0;i < g[u].size();i++)
            {
                edge &e = edges[g[u][i]];
                v = e.v;
                if(!vis[v] && e.cap-e.flow > 0)
                {
                    vis[v] = 1;
                    dis[v] = dis[u] +1;
                    q.push(v);
                }
            }
        }
        return vis[t];
    }
    int dfs(int u,int a,int t)
    {
        if(u == t || a == 0)
        return a;
        int v;
        int flow = 0,f;
        for(int& i = cur[u]; i < g[u].size();i++)
        {
            edge &e = edges[g[u][i]];
            v = e.v;
            if(dis[u]+1 == dis[v] &&(f = dfs(v,min(a,e.cap-e.flow),t)))
            {
                e.flow += f;
                edges[g[u][i]^1].flow -= f;
                flow += f;
                a -= f;
                if(a == 0)
                break;
            }
        }
     
        return flow;
    }
    int maxflow(int s,int t)
    {
        int flow = 0;
        while(bfs(s,t,t))
        {
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,1000050,t);
        }
        return flow;
    }
     
     
    int main()
    {
        int i,j;
        int t;
         
        while(~scanf("%d",&t))
        {
            while(t--)
            {
                scanf("%d %d",&m,&n);
                init(100+m);
                int u,v;
                int word[30];
                for(u = 1;u <= m;u++)
                {
                    addedge(0,u,1,0);
                    char str[5005];
                    scanf("%s",str);
                    memset(word,0,sizeof(word));
                    for(i = 0;str[i] != '\0';i++)
                    {
                        if(str[i] >= 'a' && str[i] <= 'z')
                        str[i]-=32;
                        v = str[i]-'A';
     
                        if(!word[v])
                        addedge(u,m+v+1,1,0);
                        word[v] = 1;
     
                    }
                }
                int ans = 0;
                ed = edges;
                for(i = 0;i <= m+28;i++)
                G[i] = g[i];
                for(u = 1;u <= n;u++)
                {
     
                    edges = ed;
                    memset(word,0,sizeof(word));
                    for(i = 0;i <= m+28;i++)
                    g[i] = G[i];
                    char str[5005];
                    scanf("%s",str);
                    int len,res;
                    len = strlen(str);
     
                    for(i = 0;i < len;i++)
                    {
                        if(str[i] >= 'a' && str[i]<='z')
                        str[i] -= 32;
                        v  = str[i]-'A';
                        word[v]++;
     
                    }
                    for(i = 0;i <= 25;i++)
                    {
                        if(word[i])
                        addedge(m+i+1,m+27,word[i],0);
                    }
     
                    res = maxflow(0,m+26+1);
     
                    if(res >= len)
                    ans++;//,cout<<"yes"<<endl;
                }
                printf("%d\n",ans);
     
            }
        }
     
        return 0;
    }
    View Code
  • 相关阅读:
    数据结构笔记
    并查集
    计算两个数的最大公约数和最小公倍数
    行盒
    浏览器兼容性和布局
    Java中HashMap等的实现要点浅析
    关于js异步上传文件
    填充路径时所使用的 “非零环绕规则”
    XP极限编程
    假如森林里有一棵树倒下了
  • 原文地址:https://www.cnblogs.com/0803yijia/p/3083016.html
Copyright © 2011-2022 走看看