zoukankan      html  css  js  c++  java
  • UVA 11045 My T-shirt suits me

    一开始就想到网络流。。后来一想暴力能不能过。自己写的T了。看了别人有暴力过的。

    暴力的思路就是6进制数字表示给予的衣服的数量。然后每个人的需求表示成01 的6位串然后爆搜。

    网络流就建一个源一个汇 然后针对输入 i  - i + 6 边权为N/6; 然后M个人由衣服连M个人边权为1。与源直接相连的点就INF求最大流值判断即可。

    别人的建图更简单一些。不需要设置INF;思路一样

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    int src,tag;
    int N,M;
    const int INF = 0x3f3f3f3f ;
    char size[10][20] = {"xxa","XXL","XL","L","M","S","XS"};
    int d[100],cap[100][100];
    bool inq[100];
    int flow[100][100];
    int p[100];
    void read()
    {
        scanf("%d%d",&N,&M);
        N /= 6;
        memset(cap,0,sizeof(cap));
        for (int i = 1; i <= 6; i++)  { cap[0][i] = INF; cap[i][i + 6] = N; }
        for (int j = 1; j <= M; j++)
        {
            char a[8],b[8];
            scanf("%s%s",a,b);
            int s1 = -1, s2;
            for (int i = 1; i <= 6; i++)
            {
                if (strcmp(size[i],a) == 0)
                     s1 = i;
                if (strcmp(size[i],b) == 0)
                     s2 = i;
            }
            //printf("%d %d
    ",s1,s2);
            cap[s1 + 6][12 + j] = 1;
            cap[s2 + 6][12 + j] = 1;
            cap[12 + j][12 + M + 1] = 1;
        }
        src = 0;
        tag = 12 + M + 1;
    }
    int Edmons_karp()
    {
        queue<int>q;
        int a[100];
        while (!q.empty()) q.pop();
        memset(flow,0,sizeof(flow));
        int ans = 0;
        while (true)
        {
            memset(a,0,sizeof(a));
            a[src] = INF;
            q.push(src);
            while(!q.empty())
            {
                int u = q.front(); q.pop();
                for (int v = 1; v <= tag; v++)
                    if (!a[v] && cap[u][v] > flow[u][v])
                {
                    p[v] = u;
                    q.push(v);
                    a[v] = min(a[u],cap[u][v] - flow[u][v]);
                }
            }
            if (a[tag] == 0) break;
            for (int u = tag; u != src; u = p[u])
            {
                flow[p[u]][u] += a[tag];
                flow[u][p[u]] -= a[tag];
            }
            ans += a[tag];
        }
        return ans;
    }
    int main()
    {
        //freopen("sample.txt","r",stdin);
        int T;
        scanf("%d",&T);
        while (T--)
        {
            read();
            int ans = Edmons_karp();
            //printf("%d
    ",ans);
            if (ans >= M) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }

    TLE 的代码也贴一下吧

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    int st[32];
    int N,M;
    bool found;
    char size[10][20] = {"XXL","XL","L","M","S","XS"};
    int res;
    void read()
    {
        res = 0;
        scanf("%d%d",&N,&M);
        N /= 6;
        char tmp[10];
        for (int i = 0; i < 6 ; i++)
            tmp[i] = N + '0';
        tmp[6] = '';
        sscanf(tmp,"%d",&res);
        memset(st,0,sizeof(st));
        for (int i = 1; i <= M; i++)
        {
            char a[6],b[6];
            scanf("%s%s",a,b);
            int j;
            for (j = 0; j < 6; j++) if (strcmp(a,size[j]) == 0) break;
            st[i] |= 1 << j;
            for (j = 0; j < 6; j++) if (strcmp(b,size[j]) == 0) break;
            st[i] |= 1 << j;
        }
    }
    void calcu(int cur, int sta, int cnt)
    {
        if (found) return ;
        if (cnt >= M) { found = true; return ; }
        int temp = sta;
        bool change = false;
        char str[20];
        for (int i = cur; i <= M; i++)
        {
            int a = -1,b = -1;
            for (int j = 0; j < 6; j++)
            {
                if (st[i] & (1 << j))
                {
                    if (a == -1)
                    {
                        a = j;
                    }
                    else
                        b = j;
                }
            }
            sprintf(str,"%d",temp);
            if (str[a] - '0' > 0)
            {
                change = true;
                str[a]--;
                sscanf(str,"%d",&temp);
                calcu(cur + 1, temp, cnt + 1);
                str[a]++;
            }
            temp = sta;
            if (str[b] - '0' > 0)
            {
                change = true;
                str[b]--;
                sscanf(str,"%d",&temp);
                calcu(cur + 1, temp, cnt + 1);
                str[b]++;
            }
            if (!change) return ;
        }
    }
    int main()
    {
        //freopen("sample.txt","r",stdin);
        int T;
        scanf("%d",&T);
        while (T--)
        {
            found = false;
            read();
            calcu(1,res,0);
            if (found) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    梅小雨20191010-2 每周例行报告
    梅小雨20190919-1 每周例行报告
    梅小雨20190919-4 单元测试,结对
    王可非 20191128-1 总结
    20191121-1 每周例行报告
    20191114-1 每周例行报告
    对“都是为了生活”小组成员帮助的感谢
    20191107-1 每周例行报告
    20191031-1 每周例行报告
    20191024-1 每周例行报告
  • 原文地址:https://www.cnblogs.com/Commence/p/4020337.html
Copyright © 2011-2022 走看看