zoukankan      html  css  js  c++  java
  • SPOJ:Dandiya Night and Violence(Bitset优化)

    It is Dandiya Night! A certain way how dandiya is played is described:

    There are N pairs of people playing at a time. Both the person in a pair are playing Dandiya with each other. Since a person might get bored with the same partner, he can swap with a friend in a different pair. For example, if (1, 2) and (3, 4) are initial pairs, and if 1 and 3 are friends, they can swap, and a possible configuration of pairs will be (3, 2) and (1, 4). Friendship relation is transitive in nature. (x,y) and (y, z) friendship pairs imply a (x, z) friendship pair.

    Now, Dandiyas are dangerous if not used carefully, and there are always pairs of people who would like to engage in a violent dandiya encounter. A violent dandiya encounter occurs in a pair (5, 6) if 5 and 6 are enemies (not friends). ACM is present at the Dandiya Night and is concerned about this situation.

    Given the initial arrangement of pairs, help us to determine the maximum number of violent dandiya encounters possible over the entire Dandiya Night.

    Note: A pair (x, y) is unordered, i.e., both (x, y) and (y, x) should be considered the same.

    Input

    First line denotes number of test cases T.
    T test cases follow.
    Each test case is formatted as First line consist of integers N, F (N = Number of pairs, F = Number of Friend pairs)
    N lines follow, each consisting of two integers, which denote an initial pair of Dandiya Night 
    (People are numbered from 1 to 2*N) 
    F lines follow, each denoting a pair of friends.

    T<=100
    1<=N<=200 
    0<=F<=min(5000, C(2*N, 2)) (C(n, k) = Binomial Coefficient)

    Output

    For each Test case, output a line consisting of an integer denoting the maximum possible violent dandiya encounters.

    Example

    Input:

    2
    2 1
    1 2
    3 4
    1 3
    4 3
    1 2
    3 4
    5 6
    7 8
    1 2
    2 3
    5 4 Output: 4
    9

    题意:有2*N个人,开始他们组好了队比赛,而且知道他们之间的好友关系(F组),好友的好友也是自己的好友;比赛时,好友可以换位置,问可能产生多少组队,两个成员不是好友。有T组数据。

    思路:模拟即可,但是注意必须将N^3*T优化为N^2*T或者更优。需要bitset。同时,注意不要用mp取更新q。 

    (建议自己写一发,才知道这题蛮坑的!

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=410;
    bitset<maxn>mp[maxn];
    int vis[maxn][maxn];
    int q[maxn*maxn][2],head,tail;
    int main()
    {
        int T,N,M,x,y,k,i,j,ans;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&N,&M); head=tail=ans=0;
            for(i=1;i<=N+N;i++)
              for(j=1;j<=N+N;j++)
                 vis[i][j]=0;
            for(i=1;i<=N+N;i++) mp[i].reset();
            for(i=1;i<=N;i++){
               scanf("%d%d",&x,&y);
               if(x>y) swap(x,y);
               if(!vis[x][y]){
                  q[++head][0]=x; q[head][1]=y;
                  vis[x][y]=1;
               }
            }
            N<<=1;
            for(i=1;i<=M;i++){
                scanf("%d%d",&x,&y);
                mp[x][y]=mp[y][x]=1;
            }
            for(k=1;k<=N;k++)
             for(i=1;i<=N;i++)
              if(mp[i][k])
               mp[i]|=mp[k];
            while(tail<head){
                tail++;
                x=q[tail][0]; y=q[tail][1];
                for(i=1;i<=N;i++){
                    int ty=y; if(ty>)
                    if(mp[x][i]&&!vis[i][y]) q[++head][0]=i,q[+head][1]=y,vis[i][y]=1;
                }
                for(i=1;i<=N;i++) if(mp[y][i]&&!vis[x][i]) q[++head][0]=x,q[+head][1]=i,vis[x][i]=1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    bzoj3996: [TJOI2015]线性代数
    bzoj3319: 黑白树
    bzoj3745: [Coci2015]Norma
    bzoj2437: [Noi2011]兔兔与蛋蛋
    bzoj1110: [POI2007]砝码Odw
    bzoj4919: [Lydsy1706月赛]大根堆
    bzoj5085: 最大
    bzoj2721: [Violet 5]樱花
    Theoretical & Applied Mechanics Letters第2届编委会2015年度第1次全体编委会工作会议纪要(转自力学学会)
    法国石墨烯研究者成功合成二维材料锗烯
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9064583.html
Copyright © 2011-2022 走看看