青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

強(qiáng)烈推薦此題。圖論和DP結(jié)合。
首先,我們分析一下分組的要求:
1、把所有的人分成2組,每組至少有1人;
2、每組之間的人兩兩認(rèn)識(shí)。
    非常明顯,如果存在兩個(gè)人A和B,A不認(rèn)識(shí)B,或B不認(rèn)識(shí)A,那么A和B一定不能分在同一組。因此,我們以人為結(jié)點(diǎn)重新構(gòu)造一個(gè)圖G。假如A和B不能分在同一組,那么就在G中增加一條無向邊(A,B)。這樣,我們就得到了一個(gè)較為“單純”的模型。下面我們對(duì)這個(gè)模型進(jìn)行簡(jiǎn)單分析。
    我們先研究G的一個(gè)連通分量K1。對(duì)于這個(gè)連通分量,可以先求出K1的生成樹T1。對(duì)于K1中的任意結(jié)點(diǎn)a,假如a在T1中的深度為奇數(shù),我們就把a(bǔ)加入點(diǎn)集S1;否則我們把a(bǔ)加入點(diǎn)集S2(S1,S2最初為空集)。顯然最后S1,S2的交集為空。
    不難證明,如果存在不同結(jié)點(diǎn)p和q,p和q同屬于S1或S2,而且G中存在邊(p,q),那么要做到滿足題目要求的分組是不可能的,應(yīng)輸出No solution。否則,我們就得到了連通分量K1的唯一分組方案:分為S1,S2兩組。
    對(duì)于G中的每個(gè)連通分量Ki,我們可以求出相應(yīng)的S1i,S2i。最后,我們的目的是把全部人分為2組。也就是說,對(duì)于i=1,2,3,...,m,我們必須決定把S1i中的人分到第1組,S2i中的人分到第2組,還是做剛好相反的處理。由于題目要求最后兩組的總?cè)藬?shù)差最小,我們可以用動(dòng)態(tài)規(guī)劃的辦法來確定究竟選取上面的哪種決策。
    不妨假設(shè)G中共有m個(gè)連通分量,記|S1i|=xi,|S2i|=yi(i=1,2,3,...,m)。若xi < yi,我們就交換xi和yi(這樣不影響結(jié)果的正確性)。記wi = xi - yi。那么只要對(duì)所有的wi做“半個(gè)背包”即可。也就是說,湊出盡量接近sum(wi)的數(shù)。接下去就非常簡(jiǎn)單了。


/*************************************************************************
Author: WHU_GCC
Created Time: 2007-8-29 12:07:38
File Name: pku1112.cpp
Description: 
***********************************************************************
*/

#include 
<iostream>
#include 
<vector>
using namespace std;
#define out(x) (cout << #x << ": " << x << endl)
const int maxint = 0x7FFFFFFF;
typedef 
long long int64;
const int64 maxint64 = 0x7FFFFFFFFFFFFFFFLL;
template 
<class T> void show(T a, int n) {for (int i = 0; i < n; ++i) cout << a[i] << ' '; cout << endl; }
template 
<class T> void show(T a, int r, int l) {for (int i = 0; i < r; ++i) show(a[i], l); cout << endl; }

const int maxn = 110;

int n;
int g[maxn][maxn];

int cnt_id;
int id[maxn];
int w[maxn];

void dfs(int now, int new_id)
{
    id[now] 
= new_id;
    
for (int i = 1; i <= n; i++if (id[i] == 0 && g[now][i])
        dfs(i, new_id);
}


void make_id()
{
    cnt_id 
= 0;
    memset(id, 
0sizeof(id));
    
for (int i = 1; i <= n; i++if (id[i] == 0)
        dfs(i, 
++cnt_id);
}


int set_mask[maxn];

void divide(int cid, int now, int set_id, int *set_mask)
{
    
*(set_mask + now) = set_id;
    
for (int i = 1; i <= n; i++if (*(set_mask + i) == 0 && id[i] == cid && g[now][i])
        divide(cid, i, 
3 - set_id, set_mask);
}


int ok()
{
    memset(set_mask, 
0sizeof(set_mask));
    
for (int i = 1; i <= cnt_id; i++)
    
{
        
for (int j = 1; j <= n; j++)
            
if (id[j] == i)
            
{
                divide(i, j, 
1, set_mask);
                
break;
            }

        
int cntx = 0;
        
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 1)
            cntx
++;

        
int cnty = 0;
        
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 2)
            cnty
++;
        
if (cntx < cnty)
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i)
                set_mask[j] 
= 3 - set_mask[j];
        }

        
        w[i] 
= abs(cntx - cnty);
        
        
int flag = 1;
        
for (int j = 1; j <= n && flag; j++if (id[j] == i && set_mask[j] == 1)
            
for (int k = 1; k <= n && flag; k++if (id[k] == i && set_mask[k] == 1 && j != k)
                
if (g[j][k]) flag = 0;
        
for (int j = 1; j <= n && flag; j++if (id[j] == i && set_mask[j] == 2)
            
for (int k = 1; k <= n && flag; k++if (id[k] == i && set_mask[k] == 2 && j != k)
                
if (g[j][k]) flag = 0;
        
if (flag == 0return 0;
    }

    
return 1;
}


typedef 
struct ptr_t
{
    
int ptr, value;
}
;

ptr_t pre[maxn];
int mask[maxn];

void print(int now)
{
    
if (pre[now].value == 0)
        
return;
    print(pre[now].ptr);
    mask[pre[now].value] 
= 1;
}


void dp()
{
    
int f[maxn];

    memset(f, 
0sizeof(f));
    memset(pre, 
0sizeof(pre));
    f[
0= 1;
    
int sum = 0;
    
for (int i = 1; i <= cnt_id; i++) sum += w[i];
    
for (int i = 0; i <= cnt_id; i++)
        
for (int j = sum / 2; j >= 0; j--if (f[j] && !f[j + w[i]])
        
{
            f[j 
+ w[i]] = 1;
            pre[j 
+ w[i]].ptr = j;
            pre[j 
+ w[i]].value = i;
        }

    
int ans_i;
    
for (int i = sum / 2; i >= 0; i--if (f[i])
    
{
        ans_i 
= i;
        
break;
    }

    memset(mask, 
0sizeof(mask));
    print(ans_i);

    
int cnt1 = 0;
    
for (int i = 1; i <= cnt_id; i++)
    
{
        
if (mask[i])
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 1)
                cnt1
++;
        }

        
else
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 2)
                cnt1
++;
        }

    }

    printf(
"%d", cnt1);
    
for (int i = 1; i <= cnt_id; i++)
    
{
        
if (mask[i])
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 1)
                printf(
" %d", j);
        }

        
else
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 2)
                printf(
" %d", j);
        }

    }

    printf(
"\n");
    
    
int cnt2 = 0;
    
for (int i = 1; i <= cnt_id; i++)
    
{
        
if (mask[i])
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 2)
                cnt2
++;
        }

        
else
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 1)
                cnt2
++;
        }

    }

    printf(
"%d", cnt2);
    
for (int i = 1; i <= cnt_id; i++)
    
{
        
if (mask[i])
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 2)
                printf(
" %d", j);
        }

        
else
        
{
            
for (int j = 1; j <= n; j++if (id[j] == i && set_mask[j] == 1)
                printf(
" %d", j);
        }

    }

    printf(
"\n");
    
}


int main()
{
    
int tmp[maxn][maxn];
    
while (scanf("%d"&n) != EOF)
    
{
        memset(tmp, 
0sizeof(tmp));
        
for (int i = 1; i <= n; i++)
        
{
            
int t;
            
while (scanf("%d"&t), t != 0)
                tmp[i][t] 
= 1;
        }

        memset(g, 
0sizeof(g));
        
for (int i = 1; i <= n; i++)
            
for (int j = 1; j <= n; j++)
                
if (i != j && (tmp[i][j] == 0 || tmp[j][i] == 0))
                    g[i][j] 
= g[j][i] = 1;
        make_id();
        
int t = ok();
        
if (!t)
            printf(
"No solution\n");
        
else
            dp();
    }

    
return 0;
}
posted on 2007-08-29 17:15 Felicia 閱讀(938) 評(píng)論(4)  編輯 收藏 引用 所屬分類: 動(dòng)態(tài)規(guī)劃
Comments
  • # re: [動(dòng)態(tài)規(guī)劃]pku1112
    tmwli
    Posted @ 2007-09-17 16:24
    just this problem, hit, yesterday...
    do not know how to solve it.  回復(fù)  更多評(píng)論   
  • # re: [動(dòng)態(tài)規(guī)劃]pku1112
    Felicia
    Posted @ 2007-09-17 16:27
    @tmwli
    你說的是昨天HIT的A題吧……
    那個(gè)題用匹配做的,題意和這個(gè)題不一樣
      回復(fù)  更多評(píng)論   
  • # re: [動(dòng)態(tài)規(guī)劃]pku1112
    whl
    Posted @ 2009-05-20 14:10
    f[i] 含義是什么呀

      回復(fù)  更多評(píng)論   
  • # re: [動(dòng)態(tài)規(guī)劃]pku1112
    whl
    Posted @ 2009-05-20 14:30
    dp() 這段代碼好難懂。 :(  回復(fù)  更多評(píng)論   
 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲激情专区| 欧美专区在线观看一区| 亚洲午夜一区二区| 在线一区日本视频| 亚洲一区视频在线观看视频| 亚洲欧美日韩视频一区| 欧美在线亚洲综合一区| 米奇777在线欧美播放| 亚洲国产精品福利| 99这里只有精品| 欧美伊人久久大香线蕉综合69| 欧美一区影院| 欧美大片免费观看在线观看网站推荐| 欧美日韩成人在线| 麻豆九一精品爱看视频在线观看免费| 国产精品久久激情| 国产一区二区三区视频在线观看 | 免费不卡中文字幕视频| 91久久在线观看| 亚洲免费网址| 欧美成年人视频| 国产美女精品人人做人人爽| 在线看国产日韩| 亚洲一区二区精品在线| 麻豆av福利av久久av| av72成人在线| 农夫在线精品视频免费观看| 国产毛片精品视频| 妖精成人www高清在线观看| 久久精品国产77777蜜臀 | 亚洲高清久久| 亚洲欧美日韩一区二区三区在线观看 | 国产日韩欧美在线观看| 亚洲人午夜精品| 久久精品在线视频| 中文精品视频一区二区在线观看| 久久精品国产91精品亚洲| 欧美日韩久久不卡| 在线不卡亚洲| 久久久久国产精品一区二区| 日韩一级在线观看| 欧美成人精品一区二区| 国产一区二区三区日韩欧美| 亚洲综合欧美日韩| 99国产精品视频免费观看一公开| 久久免费精品视频| 国内成+人亚洲+欧美+综合在线| 亚洲一区观看| 最新国产の精品合集bt伙计| 美女精品国产| 亚洲国内自拍| 能在线观看的日韩av| 久久精品视频免费播放| 国产亚洲一区精品| 久久精品一区四区| 久久超碰97中文字幕| 国户精品久久久久久久久久久不卡 | 国产精品99久久久久久有的能看| 欧美成人在线免费视频| 99这里只有久久精品视频| 亚洲国产精品va在线看黑人| 久久免费视频一区| 在线成人欧美| 欧美aaa级| 欧美成人午夜| 亚洲精品乱码久久久久久蜜桃麻豆 | 欧美一区成人| 狠狠色狠狠色综合日日tαg| 久久久久国产精品人| 久久精品国产亚洲一区二区| 在线电影一区| 亚洲国内高清视频| 欧美欧美全黄| 先锋a资源在线看亚洲| 亚洲欧美综合一区| 加勒比av一区二区| 亚洲国产一区二区三区在线播| 欧美日韩播放| 久久激情中文| 欧美成人69av| 午夜精品在线观看| 久久亚洲一区二区| 亚洲一区二区在线播放| 欧美一区二区成人| 亚洲伦理精品| 午夜欧美不卡精品aaaaa| 在线成人激情| 亚洲视频久久| 在线成人激情视频| 一区二区电影免费在线观看| 国产亚洲人成a一在线v站| 亚洲第一福利在线观看| 国产精品一二三视频| 欧美激情在线免费观看| 国产精品久久久久久久久婷婷| 美国成人毛片| 国产精品久久久久9999吃药| 嫩草成人www欧美| 国产九九精品视频| 亚洲国产高清在线观看视频| 国产欧美日韩视频一区二区三区 | 亚洲国产cao| 国产欧美精品一区| 亚洲在线中文字幕| 激情五月综合色婷婷一区二区| 亚洲美女av黄| 亚洲国产精品精华液网站| 一区二区三区高清在线观看| 在线观看欧美日本| 亚洲欧美视频一区| 一本高清dvd不卡在线观看| 欧美一区二区黄色| 亚洲性xxxx| 欧美精品一区二区三区高清aⅴ| 美女国产一区| 国产综合色产在线精品| 欧美电影专区| 国产夜色精品一区二区av| 亚洲免费成人av电影| 亚洲黄页视频免费观看| 欧美在线首页| 久久精品天堂| 国产欧美日本一区二区三区| 一本到12不卡视频在线dvd| 亚洲精品一区在线| 久久这里只有| 免费亚洲一区| 激情视频一区二区三区| 久久www免费人成看片高清| 欧美制服丝袜第一页| 国产精品嫩草影院一区二区| 在线午夜精品| 亚洲影视九九影院在线观看| 欧美日韩久久不卡| 日韩视频一区二区三区| 一区二区免费在线播放| 欧美理论在线播放| 亚洲美女色禁图| 亚洲视频一区二区在线观看 | 久久久久国产精品午夜一区| 国产麻豆精品theporn| 香蕉成人伊视频在线观看| 欧美一区二区视频在线| 国产美女精品视频| 久久精品道一区二区三区| 免费中文字幕日韩欧美| 亚洲国产日韩在线一区模特| 麻豆成人小视频| 亚洲精品护士| 亚洲一区二区三区高清 | 99国产精品久久久久久久| 欧美精品一区二区三区很污很色的 | 亚洲国产日韩一级| 一区二区三区视频在线| 国产精品美女久久久久久免费| 亚洲欧美自拍偷拍| 欧美成人嫩草网站| 一区二区三区日韩欧美精品| 国产精品综合视频| 久久色在线观看| 亚洲精品美女在线观看| 午夜精品一区二区三区电影天堂| 国产日韩欧美成人| 欧美成在线观看| 亚洲伊人观看| 免费在线亚洲| 亚洲午夜小视频| 国产综合自拍| 欧美日韩中文在线观看| 久久国产66| av成人福利| 免费观看在线综合| 亚洲女性喷水在线观看一区| 在线观看三级视频欧美| 亚洲高清不卡一区| 久久久水蜜桃| 一区二区欧美日韩| 久久一区免费| 中日韩男男gay无套| 国内欧美视频一区二区| 欧美日韩精品免费看| 久久成人精品视频| 99热在这里有精品免费| 免费短视频成人日韩| 亚洲欧美日韩成人| 亚洲美女91| 在线观看成人网| 国产乱人伦精品一区二区 | 国产一区二区三区网站| 欧美三级资源在线| 欧美超级免费视 在线| 欧美一区二区三区免费观看视频| 亚洲精品综合| 亚洲成人在线视频网站| 久久国产精品久久久久久电车| 一区二区三区不卡视频在线观看 | 亚洲精品视频免费在线观看| 欧美日韩在线播| 欧美激情一区二区三级高清视频| 久久精品一区四区|