• <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>

            【AHOI2013復(fù)仇】SCOI2008 天平

            Posted on 2012-09-25 21:26 Mato_No1 閱讀(745) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 搜索SCOI
            原題地址
            本題就是,有N個(gè)變量,其取值只可能有三種:1、2、3。現(xiàn)在已知它們之間的一些大小關(guān)系,求有多少對(duì)變量(I, J)滿足(I的值+J的值)一定>或=或<(A的值+B的值),A、B是指定的兩個(gè)變量,且I、J、A、B互不相同。
            首先,對(duì)于值相等的變量,直接建出無(wú)向圖,按連通塊縮點(diǎn),再考慮大于/小于關(guān)系,如果I的值大于J則在I所在連通塊與J所在連通塊之間連一條有向邊(從I到J)……這樣,凡是既有前趨,又有后繼的點(diǎn)(縮成的點(diǎn),下同),其值只能是2,它的所有前趨的值只能是3,所有后繼的值只能是1。除此以外,木有其它辦法能唯一確定某個(gè)變量的值。

            接下來(lái)最關(guān)鍵的一步——枚舉I、J以及I、J、A、B的值,判斷是否合法:
            (1)如果某個(gè)變量的值已確定,且與枚舉的值不同,不合法;
            (2)如果某個(gè)變量有前趨,那么它的值就不能是3;如果有后繼,那么它的值就不能是1;
            (3)(這是最容易搞疵的)對(duì)于I、J、A、B之間已知的大小關(guān)系,要判斷是否能全部滿足,注意這里的I、J、A、B是指縮成以后的點(diǎn),而不是原來(lái)的變量(本沙茶一開始用原來(lái)的變量判斷,結(jié)果WA了,后來(lái)把數(shù)據(jù)弄下來(lái)看了一下,是這里搞疵了囧……不過(guò)只跪了2個(gè)點(diǎn),總共20個(gè)點(diǎn)),因?yàn)橛锌赡芩鼈儽旧碇g木有給出關(guān)系,但那些與它在一個(gè)連通塊中的(即與它值相等)的變量之間給出了關(guān)系。

            至于枚舉……由于本題數(shù)據(jù)小,只需要暴力枚舉就行了囧……

            本題的啟示:考慮問(wèn)題要周全,要設(shè)法考慮到所有情況。

            代碼:
            #include <iostream>
            #include 
            <stdio.h>
            #include 
            <stdlib.h>
            #include 
            <string.h>
            using namespace std;
            #define re(i, n) for (int i=0; i<n; i++)
            #define re1(i, n) for (int i=1; i<=n; i++)
            #define re2(i, l, r) for (int i=l; i<r; i++)
            #define re3(i, l, r) for (int i=l; i<=r; i++)
            #define rre(i, n) for (int i=n-1; i>=0; i--)
            #define rre1(i, n) for (int i=n; i>0; i--)
            #define rre2(i, r, l) for (int i=r-1; i>=l; i--)
            #define rre3(i, r, l) for (int i=r; i>=l; i--)
            #define ll long long
            const int MAXN = 61, MAXM = 8000, INF = ~0U >> 2;
            struct edge {
                
            int a, b, pre, next;
            } _E[MAXM 
            + MAXM + MAXN], E[MAXM + MAXM + MAXN], E2[MAXM + MAXM + MAXN];
            int n, _m, m, No1, No2;
            int n0, A[MAXN][MAXN], A2[MAXN][MAXN], Q[MAXN], D[MAXN], W[MAXN], ST[MAXN][MAXN], res1 = 0, res2 = 0, res3 = 0;
            bool vst[MAXN];
            char ss[MAXN + 1];
            void init_d0()
            {
                re(i, n) _E[i].pre 
            = _E[i].next = i;
                
            if (n & 1) _m = n + 1else _m = n;
            }
            void init_d()
            {
                re(i, n0) E[i].pre 
            = E[i].next = E2[i].pre = E2[i].next = i; m = n0;
            }
            void add_edge0(int a, int b)
            {
                _E[_m].a 
            = a; _E[_m].b = b; _E[_m].pre = _E[a].pre; _E[_m].next = a; _E[a].pre = _m; _E[_E[_m].pre].next = _m++;
                _E[_m].a 
            = b; _E[_m].b = a; _E[_m].pre = _E[b].pre; _E[_m].next = b; _E[b].pre = _m; _E[_E[_m].pre].next = _m++;
            }
            void add_edge(int a, int b)
            {
                E[m].a 
            = a; E[m].b = b; E[m].pre = E[a].pre; E[m].next = a; E[a].pre = m; E[E[m].pre].next = m;
                E2[m].a 
            = b; E2[m].b = a; E2[m].pre = E2[b].pre; E2[m].next = b; E2[b].pre = m; E2[E2[m].pre].next = m++;
            }
            void init()
            {
                scanf(
            "%d%d%d"&n, &No1, &No2); init_d0(); No1--; No2--;
                re(i, n) {
                    scanf(
            "%s", ss);
                    re(j, n) 
            if (i != j) {
                        
            if (ss[j] == '?') A[i][j] = 0;
                        
            else if (ss[j] == '+') A[i][j] = 1;
                        
            else if (ss[j] == '-') A[i][j] = 2else {A[i][j] = 3; add_edge0(i, j);}
                    }
                }
            }
            void prepare()
            {
                re(i, n) re(j, n) 
            if (i != j) {
                    
            if (A[i][j] == 1) A[j][i] = 2;
                    
            if (A[i][j] == 2) A[j][i] = 1;
                    
            if (A[i][j] == 3) A[j][i] = 3;
                }
                re(i, n) {W[i] 
            = 0; vst[i] = 0;} int x, y; n0 = 0;
                re(i, n) 
            if (!vst[i]) {
                    vst[i] 
            = 1; Q[0= i; D[i] = n0;
                    
            for (int front=0, rear=0; front<=rear; front++) {
                        x 
            = Q[front];
                        
            for (int p=_E[x].next; p != x; p=_E[p].next) {
                            y 
            = _E[p].b;
                            
            if (!vst[y]) {vst[y] = 1; Q[++rear] = y; D[y] = n0;}
                        }
                    }
                    n0
            ++;
                }
                init_d(); re(i, n0) re(j, n0) A2[i][j] 
            = 0;
                re(i, n) re(j, n) 
            if (D[i] != D[j]) {
                    
            if (A[i][j] == 1) add_edge(D[i], D[j]); else if (A[i][j] == 2) add_edge(D[j], D[i]);
                }
                re(i, n) re(j, n) 
            if (i != j && A[i][j]) A2[D[i]][D[j]] = A[i][j];
            }
            void solve()
            {
                
            int x; re(i, n) re(j, n) ST[i][j] = 0;
                re(i, n0) 
            if (E[i].next != i && E2[i].next != i) {
                    W[i] 
            = 2;
                    
            for (int p=E[i].next; p != i; p=E[p].next) {
                        x 
            = E[p].b; W[x] = 1;
                    }
                    
            for (int p=E2[i].next; p != i; p=E2[p].next) {
                        x 
            = E2[p].b; W[x] = 3;
                    }
                }
                
            int d1 = D[No1], d2 = D[No2], di, dj;
                re(i, n) re2(j, i
            +1, n) if (i != No1 && i != No2 && j != No1 && j != No2) {
                    di 
            = D[i]; dj = D[j];
                    re1(si, 
            3) {re1(sj, 3) {re1(s1, 3) {re1(s2, 3) {
                        
            if (W[di] && si != W[di]) continue;
                        
            if (W[dj] && sj != W[dj]) continue;
                        
            if (W[d1] && s1 != W[d1]) continue;
                        
            if (W[d2] && s2 != W[d2]) continue;
                        
            if (E[di].next != di && si == 1continue;
                        
            if (E2[di].next != di && si == 3continue;
                        
            if (E[dj].next != dj && sj == 1continue;
                        
            if (E2[dj].next != dj && sj == 3continue;
                        
            if (E[d1].next != d1 && s1 == 1continue;
                        
            if (E2[d1].next != d1 && s1 == 3continue;
                        
            if (E[d2].next != d2 && s2 == 1continue;
                        
            if (E2[d2].next != d2 && s2 == 3continue;
                        
            if (A2[di][dj] == 1 && si <= sj) continue;
                        
            if (A2[di][dj] == 2 && si >= sj) continue;
                        
            if (A2[di][dj] == 3 && si != sj) continue;
                        
            if (A2[di][d1] == 1 && si <= s1) continue;
                        
            if (A2[di][d1] == 2 && si >= s1) continue;
                        
            if (A2[di][d1] == 3 && si != s1) continue;
                        
            if (A2[di][d2] == 1 && si <= s2) continue;
                        
            if (A2[di][d2] == 2 && si >= s2) continue;
                        
            if (A2[di][d2] == 3 && si != s2) continue;
                        
            if (A2[dj][d1] == 1 && sj <= s1) continue;
                        
            if (A2[dj][d1] == 2 && sj >= s1) continue;
                        
            if (A2[dj][d1] == 3 && sj != s1) continue;
                        
            if (A2[dj][d2] == 1 && sj <= s2) continue;
                        
            if (A2[dj][d2] == 2 && sj >= s2) continue;
                        
            if (A2[dj][d2] == 3 && sj != s2) continue;
                        
            if (A2[d1][d2] == 1 && s1 <= s2) continue;
                        
            if (A2[d1][d2] == 2 && s1 >= s2) continue;
                        
            if (A2[d1][d2] == 3 && s1 != s2) continue;
                        
            if (s1 + s2 > si + sj) x = 1;
                        
            else if (s1 + s2 == si + sj) x = 2else x = 3;
                        
            if (!ST[i][j]) ST[i][j] = x; else if (ST[i][j] != x) {ST[i][j] = -1break;}
                    } 
            if (ST[i][j] == -1break;} if (ST[i][j] == -1break;} if (ST[i][j] == -1break;}
                }
                re(i, n) re2(j, i
            +1, n) if (ST[i][j] == 1) res1++else if (ST[i][j] == 2) res2++else if (ST[i][j] == 3) res3++;
            }
            void pri()
            {
                printf(
            "%d %d %d\n", res1, res2, res3);
            }
            int main()
            {
                init();
                prepare();
                solve();
                pri();
                
            return 0;
            }
            麻豆成人久久精品二区三区免费| 久久SE精品一区二区| 97久久超碰国产精品旧版| 久久久久亚洲av综合波多野结衣 | 久久99精品久久久久子伦| 亚洲va久久久噜噜噜久久男同| 激情伊人五月天久久综合| 久久久久国产精品麻豆AR影院 | 久久99免费视频| 久久国产视屏| 国内精品久久久久影院日本| 国产成人香蕉久久久久| 亚洲乱码精品久久久久..| 国产精品久久久久久久午夜片 | 亚洲天堂久久精品| 蜜桃麻豆WWW久久囤产精品| 丁香五月网久久综合| 久久中文字幕精品| 精品久久久久久无码人妻蜜桃 | 久久亚洲sm情趣捆绑调教| 青青热久久综合网伊人| 久久综合给合久久狠狠狠97色| 久久久久无码中| 久久91这里精品国产2020| 999久久久无码国产精品| 中文精品久久久久人妻不卡| 久久无码一区二区三区少妇 | 久久99精品国产99久久6男男| 精品国产乱码久久久久软件| 亚洲国产一成久久精品国产成人综合 | 久久最近最新中文字幕大全| 麻豆成人久久精品二区三区免费| 久久人人爽人人爽人人av东京热| 国产精品综合久久第一页| 青青热久久综合网伊人| 亚洲国产精品久久久久| 99久久精品免费看国产| 国产精品美女久久久久AV福利| 久久精品国产精品亚洲精品| 色综合久久久久综合99| 久久精品亚洲男人的天堂|