1. 程式人生 > >POJ1112——Team Them Up!(動態規劃,二分圖判定)

POJ1112——Team Them Up!(動態規劃,二分圖判定)

Team Them Up!
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 7454 Accepted: 2011 Special Judge

Description

Your task is to divide a number of persons into two teams, in such a way, that: 

everyone belongs to one of the teams; 

every team has at least one member; 

every person in the team knows every other person in his team; 

teams are as close in their sizes as possible. 

This task may have many solutions. You are to find and output any solution, or to report that the solution does not exist.

Input

For simplicity, all persons are assigned a unique integer identifier from 1 to N. 

The first line in the input file contains a single integer number N (2 <= N <= 100) - the total number of persons to divide into teams, followed by N lines - one line per person in ascending order of their identifiers. Each line contains the list of distinct numbers Aij (1 <= Aij <= N, Aij != i) separated by spaces. The list represents identifiers of persons that ith person knows. The list is terminated by 0.

Output

If the solution to the problem does not exist, then write a single message "No solution" (without quotes) to the output file. Otherwise write a solution on two lines. On the first line of the output file write the number of persons in the first team, followed by the identifiers of persons in the first team, placing one space before each identifier. On the second line describe the second team in the same way. You may write teams and identifiers of persons in a team in any order.

Sample Input

5
2 3 5 0
1 4 5 3 0
1 2 5 0
1 2 3 0
4 3 2 1 0

Sample Output

3 1 3 5
2 2 4

題意:

你的任務是把一些人  分成兩組, 需要滿足以下條件: 
每個人都在一個隊伍裡
每個隊至少一個人; 
每個在隊裡的人都認識隊裡的其他人; 
兩個隊伍相差的人數儘量少. 
可能有多種解,輸出其中任何一種;或者輸出無解

思路:首先得判斷出誰和誰一定不能在一組,很自然地想到二分圖染色。只有兩個人相互認識才能在同一個隊伍。所以針對不能在同一個隊伍地人連邊,然後二分圖染色。

染色的過程中得統計不同顏色有多少人,哪些人。分成不同的連通塊。

然後問題就轉化成了,比如有m個連通塊,x[i]和y[i]代表不同的顏色。對於每個連通塊,需要在x和y中選一個,統計總人數,使得最後兩組人數差最小。

我覺得我寫得好像很複雜,但因為資料量很小所以也能過。

dp[i][j]表示一組i個人,一組j個人的狀態能否達到。

ans[i][j][k]表示該狀態可以達到的情況下,第k個連通塊選了x還是y。

最後再算一下最小值,更新結果。

寫得太浪了。。。

#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
#define MAXN 110
#define INF 1000000007

vector <int> G[MAXN];
int V;
int color[MAXN];
vector <int> x[MAXN];
vector <int> y[MAXN];
int d[MAXN][MAXN];
int dp[MAXN][MAXN];
int ans[MAXN][MAXN][MAXN];
int num=0;
bool dfs(int v,int c){
    color[v]=c;
    if(c>0)
        x[num].push_back(v);
    else
        y[num].push_back(v);
    for(int i=0;i<G[v].size();i++){
        if(color[G[v][i]]==c)
            return false;
        if(color[G[v][i]]==0&&!dfs(G[v][i],-c)){
            return false;
        }
    }
    return true;
}

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int t;
        while(scanf("%d",&t)&&t){
            d[i][t]=1;
        }
    }
    for(int i=1;i<n;i++){
        for(int j=i+1;j<=n;j++){
            if(!d[i][j]||!d[j][i])
            {
                G[i].push_back(j);
                G[j].push_back(i);
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(!color[i]){
            if(dfs(i,1)){
                num++;
            }
            else{
                printf("No solution\n");
                return 0;
            }
        }
    }
    memset(dp,0,sizeof(dp));
    vector <int>r1;
    vector <int> r2;
    int m=n/2;
    dp[0][0]=1;
    memset(ans,-1,sizeof(ans));
    for(int k=0;k<num;k++){
        for(int i=0;i<=n;i++){
            for(int j=0;j<=n;j++){
                if(dp[i][j]&&ans[i][j][k]==-1){
                    int a=x[k].size(),b=y[k].size();
                    if(dp[i+a][j+b]==0){
                        dp[i+a][j+b]=1;
                        ans[i+a][j+b][k]=0;
                        //printf("<<<%d %d %d >>>\n",i+a,j+b,ans[i+a][j+b][k]);
                        for(int t=0;t<k;t++)
                            ans[i+a][j+b][t]=ans[i][j][t];
                    }
                    if(dp[i+b][j+a]==0){
                        dp[i+b][j+a]=1;
                        ans[i+b][j+a][k]=1;
                        //printf("<<<%d %d %d >>>\n",i+b,j+a,ans[i+b][j+a][k]);
                        for(int t=0;t<k;t++)
                            ans[i+b][j+a][t]=ans[i][j][t];
                    }
                }
            }
        }
    }
    int min_f=INF;
    for(int i=1;i<=n/2;i++){
        int j=n-i;
        if(dp[i][j]){
            if((j-i)<min_f){
                r1.clear();
                r2.clear();
                for(int k=0;k<num;k++){
                    if(ans[i][j][k]==0){
                        for(int s=0;s<x[k].size();s++){
                            r1.push_back(x[k][s]);
                        }
                        for(int s=0;s<y[k].size();s++){
                            r2.push_back(y[k][s]);
                        }
                    }
                    else{
                        for(int s=0;s<y[k].size();s++){
                            r1.push_back(y[k][s]);
                        }
                        for(int s=0;s<x[k].size();s++){
                            r2.push_back(x[k][s]);
                        }
                    }
                }
            }
        }
    }
    printf("%d ",r1.size());
    for(int i=0;i<r1.size();i++)
        printf(" %d",r1[i]);
    printf("\n");
    printf("%d ",r2.size());
    for(int i=0;i<r2.size();i++)
        printf(" %d",r2[i]);
    printf("\n");
}


相關推薦

POJ1112——Team Them Up!動態規劃二分判定

Team Them Up! Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7454 Accepted: 2011 Special Judge Description Your task

UVA1627-Team them up!動態規劃

Problem UVA1627-Team them up! Total Submissions:3577  Solved:648 Time Limit: 3000 mSec Problem Description It’s frosh week, and this year

【BZOJ2442】修建草坪動態規劃單調隊列

turn ace 動態 zoj fin fine -- line amp 【BZOJ2442】修建草坪(動態規劃,單調隊列) 題面 權限題。。洛谷 題解 設\(f[i]\)表示前\(i\)個裏面選出來的最大值 轉移應該比較顯然 枚舉一個斷點的位置,轉移一下就好 \(f[i]

【BZOJ1494】【NOI2007】生成樹計數動態規劃矩陣快速冪

題面 Description 最近,小棟在無向連通圖的生成樹個數計算方面有了驚人的進展,他發現: ·n個結點的環的生成樹個數為n。 ·n個結點的完全圖的生成樹個數為n^(n-2)。這兩個發現讓小棟欣喜若狂,由此更加堅定了他繼續計算生成樹個數的 想法,他

【CF1151F】Sonya and Informatics動態規劃矩陣快速冪

f11 表示 tor 快速 sizeof format oid 當前 ostream 【CF1151F】Sonya and Informatics(動態規劃,矩陣快速冪) 題面 CF 題解 考慮一個暴力\(dp\)。假設有\(m\)個\(0\),\(n-m\)個\(1\)。

hdu 1068 Girls and Boys水題二分匹配

小記:這題看是10s,其實很水,就是點多,但邊少。所以用鄰接表會快很多。 思路:直接套二分圖匹配的模板就可以過,如果想要速度快,改成鄰接表即可, 這裡我是使用的前向星,171ms。 程式碼: #i

UVA1627-Team them up!二分判斷+動態規劃

Problem UVA1627-Team them up! Total Submissions:1228  Solved:139 Time Limit: 3000 mSec Problem Description Your task is to divide a numbe

【BZOJ4872】分手是祝願動態規劃數學期望

esp math map ostream pac mes ++i rac define 【BZOJ4872】分手是祝願(動態規劃,數學期望) 題面 BZOJ 題解 對於一個狀態,如何求解當前的最短步數? 從大到小枚舉,每次把最大的沒有關掉的燈關掉 暴力枚舉因數關就好 假設我

【BZOJ3992】序列統計動態規劃NTT

swap int 乘法 true ble spa main 們的 oid 【BZOJ3992】序列統計(動態規劃,NTT) 題面 BZOJ 題解 最裸的暴力 設\(f[i][j]\)表示前\(i\)個數,積在膜意義下是\(j\)的方案數 轉移的話,每次枚舉一個數,直接丟進去

【BZOJ1415】【NOI2005】聰聰和可可動態規劃數學期望

數學期望 class ios char for problem lin vector noi 【BZOJ1415】【NOI2005】聰聰和可可(動態規劃,數學期望) 題面 BZOJ 題解 先預處理出當可可在某個點,聰聰在某個點時 聰聰會往哪裏走 然後記憶化搜索一下就好了 #

【題解】 P1879 玉米田Corn Fields 動態規劃狀態壓縮

bad sin 是否 editor infer nbsp 一行 als clas 題目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1

【BZOJ5299】【CQOI2018】解鎖屏幕動態規劃狀態壓縮

++ src 規劃 希望 getch cstring online androi 形狀 【BZOJ5299】【CQOI2018】解鎖屏幕(動態規劃,狀態壓縮) 題面 BZOJ 洛谷 Description 使用過Android手機的同學一定對手勢解鎖屏幕不陌生。Androi

【BZOJ4654】【NOI2016】國王飲水記動態規劃斜率優化

code 奇怪 while lib show ima double 優化 .com 【BZOJ4654】【NOI2016】國王飲水記(動態規劃,斜率優化) 題面 BZOJ 洛谷 題解 首先肯定是找性質。 明確一點,比\(h_1\)小的沒有任何意義。 所以我們按照\(h\)排

【BZOJ3203】保護出題人動態規劃斜率優化

現在 bzoj3203 d+ while 我們 register 攻擊 nod http 【BZOJ3203】保護出題人(動態規劃,斜率優化) 題面 BZOJ 洛谷 題解 在最優情況下,肯定是存在某只僵屍在到達重點的那一瞬間將其打死 我們現在知道了每只僵屍到達終點的時間,因

【BZOJ1226】學校食堂動態規劃狀態壓縮

食堂 有關 轉移 mem sizeof fin 狀壓 set lin 【BZOJ1226】學校食堂(動態規劃,狀態壓縮) 題面 BZOJ 洛谷 題解 發現\(b\)很小,意味著當前這個人最壞情況下也只有後面的一小部分人在他前面拿到飯。 所以整個結果的大致順序是不會變化的。

【BZOJ4455】小星星動態規劃容斥

之間 lld algorithm std 還需要 tchar 一次 lin 還需 【BZOJ4455】小星星(動態規劃,容斥) 題面 BZOJ 洛谷 Uoj 題解 題意說簡單點就是給定一張\(n\)個點的圖和一棵\(n\)個點的樹,現在要讓圖和樹之間的點一一對應,並且如果樹

【BZOJ3294】放棋子動態規劃容斥組合數學

ref efi amp 顏色 直接 using .org bzoj mat 【BZOJ3294】放棋子(動態規劃,容斥,組合數學) 題面 BZOJ 洛谷 題解 如果某一行某一列被某一種顏色給占了,那麽在考慮其他行的時候可以直接把這些行和這些列給丟掉。 那麽我們就可以寫出一個

2018牛客多校第九場E動態規劃思維取模

pac namespace for ons mod 思維 space scan 動態規劃 #include<bits/stdc++.h>using namespace std;const long long mod=1000000007,inv=57000000

洛谷P2900 [USACO08MAR]土地征用Land Acquisition動態規劃斜率優化決策單調性線性規劃單調隊列

tps include 寫法 lan clas com mat 成了 dong 用兩種不一樣的思路立體地理解斜率優化,你值得擁有。 題意分析 既然所有的土地都要買,那麽我們可以考慮到,如果一塊土地的寬和高(其實是蒟蒻把長方形立在了平面上)都比另一塊要小,那麽肯定是直接並購,

2017烏魯木齊區域賽A動態規劃組合數學期望

ble set 可能 組合 name main i++ return soft #include<bits/stdc++.h>using namespace std;double c[110][110];double g[110];double dp[110]