zoukankan      html  css  js  c++  java
  • zoj Weekend Party

    主要代码及思想来自http://zhyu.me/acm/zoj-3526.html

    略有改动

    这题卡了很久,然后想到网络流,键一个超级源点,连所有人,流量为2,然后每个人连能与其邻座的人,流量为1

    在把每个人连超级汇点,流量为2,如果最大流等于人数两倍,就表示有解。

    源点连每个人2流量,表示一个人两边都要坐人。人数为1或2的时候特判一下,可惜,超时。

    不过,像下文一样缩点,应该可以吧。。。

    /*
    题意:n个人参加party,每个人的兴趣都是ACG (Anime, Comic and Game)
    中的一种或几种,现在要让所有人坐成一圈,并且要让相邻的人至少有一种
    共同兴趣,现在给出每个人的兴趣,问这样的安排方法是否可行。

    思路:看完题就想把每个人看作一个点,有相同兴趣的人之间连边,然后…
    然后这不是Hamilton回路嘛?!NP啊!n有64,不是很大,于是决定爆搞,
    先用Dirac 定理(判断Hamilton回路的充分性 不是必要性)判一下,不行
    再搜,然后还是TLE……想到缩点可是没想明白怎么缩,就一直悲剧到比赛结束……

    缩点方法:对于AAAAAAA这种,缩成一个点就好,一个点可以和周围连起来就
    全都能连起来;对于ACACACACA这种,要缩成两个点,因为要是剩下的只有一
    个A和一个C,缩成一个点是不行的,但是实际上是可行的;对于ACGACGACG这
    种当然就是缩成三个点了。然后图中最多只有1+1+1+2+2+2+3=12个点,直接
    DFS判断即可
    */

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct Edge 
    {
    int v, next;
    }edge[50];
    char s[7][4]={"A", "C", "G", "AC", "AG", "CG", "ACG"};
    int n, ne;
    int head[8];
    int cnt[8], f[50];
    char name[15], like[15];

    void addedge(int from, int to)
    {
    edge[ne].v=to;
    edge[ne].next=head[from];
    head[from]=ne++;
    //cout<<from<<" "<<to<<endl;
    }

    bool ok(char *s1, char *s2)
    {
    for(int i=0; s1[i]!=0; i++)
    for(int j=0; s2[j]!=0; j++)
    if(s1[i]==s2[j])
    return 1;
    return 0;
    }

    void init()
    {
    ne=0;
    memset(head, -1, sizeof(head));
    for(int i=0; i<7; i++)
    for(int j=0; j<7; j++)
    if(ok(s[i], s[j]))
    addedge(i, j);
    }

    bool dfs(int p, int d)
    {
    if(d==n+1)
    {
    if(ok(s[f[1]], s[f[n]]))
    return 1;
    return 0;
    }
    for(int i=head[p]; i!=-1; i=edge[i].next)
    {
    int v=edge[i].v;
    //cout<<v<<endl;
    if(cnt[v])
    {
    cnt[v]--;
    f[d]=v;
    if(dfs(v, d+1)) return 1;
    cnt[v]++;
    }
    }
    return 0;
    }

    int main()
    {
    init();
    while(scanf("%d", &n)!=EOF)
    {
    memset(cnt, 0, sizeof(cnt));
    for(int i=1; i<=n; i++)
    {
    scanf("%s%s", name, like);
    int len=strlen(like);
    sort(like, like+len);
    for(int j=0; j<7; j++)
    if(!strcmp(s[j], like))
    {
    cnt[j]++;
    break;
    }
    }
    //缩点
    cnt[0]=min(cnt[0], 1);
    cnt[1]=min(cnt[1], 1);
    cnt[2]=min(cnt[2], 1);
    cnt[3]=min(cnt[3], 2);
    cnt[4]=min(cnt[4], 2);
    cnt[5]=min(cnt[5], 2);
    cnt[6]=min(cnt[6], 3);
    n=0;
    for(int i=0; i<7; i++) n+=cnt[i];
    bool flag=dfs(6, 1);
    if(flag) puts("Yes");
    else puts("No");
    }
    return 0;
    }


     


     

  • 相关阅读:
    bootstrap-table实现分页、导出数据至excel
    Python求多个list的交集、并集、差集 & list 排序
    JS
    python 格式化输出(% VS format)
    pyqt5_实例:修改xml文件中节点值
    博客迁移
    Reverse is Multiplex, You Need PinTools.
    ISCC2018_leftleftrightright-Writeup
    如何在linux主机上运行/调试 arm/mips架构的binary
    强网杯2018
  • 原文地址:https://www.cnblogs.com/FreeAquar/p/2158414.html
Copyright © 2011-2022 走看看