給你一張無向圖g(v,e)。每個頂點都有乙個標號,它是乙個[0,2^31-1]內的整數。不同的頂點可能會有相同的標號。
對每條邊(u,v),我們定義其費用cost(u,v)為u的標號與v的標號的異或值。
現在我們知道一些頂點的標號。你需要確定餘下頂點的標號使得所有邊的費用和盡可能小。
輸入檔案的第一行有兩個整數n,m(1<=n<=500,0<=m<=3000),n是圖的點數,m是圖的邊數。
接下來有m行,每行有兩個整數u,v,代表一條連線u,v的邊。
接下來有乙個整數k,代表已知標號的頂點個數。接下來的k行每行有兩個整數u,p,代表點u的標號是p。假定這些u不會重複。
輸出一行乙個整數,即最小的費用和。
【分析】
由題目敘述中,我們可以很容易看到,對於每個頂點的標號數的每個二進位制位上來說,它與前後該數的其他二進位制位是完全沒有任何聯絡的,所以我們不妨把每個數的二進位制位拆開來**,然後再求每個圖的最小割就可以了。
在建圖的時候,要注意的是,需要把二進位制位上為1的和二進位制位上為0的分開連線到源點和匯點。
最後,注意重邊!
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7view codeconst
int maxn=510;8
const
int maxm=3010;9
const
int inf=10000*10000;10
using
namespace
std;
11struct
liu12
15}maps[maxn][maxn];
16int
shu[maxn],map[maxn][maxn];
17int
bh[maxn],path[maxn],dist[maxn];
1819
intn,m,k;
20long
long solve(int
times);
21void make_maps(int
times);
22bool
bfs();
23int dfs(int u,int
low);
2425
intmain()
2639 scanf("
%d",&k);
40for (i=1;i<=k;i++)
4146
47long
long ans=0;48
//注意求解次數
49for (i=0;i<=31;i++) ans+=solve(i);//
求解最大流
50 printf("
%lld
",ans);
51return0;
52}53//
求解函式
54long
long solve(int
times)
5565
//printf("%d\n",flow);
66return (long
long)flow<
68//
構圖 69
void make_maps(int
times)
7081
else 82}
83for (i=1;i<=n;i++)
84for (j=1;j<=n;j++)
8590
return;91
}92bool bfs()//
bfs構建層次網路
93110
}111
} 112
return (dist[n+1]!=-1
);113
}114
int dfs(int v,int low)//
增廣 115
131}
132}
133return
flow;
134 }
spoj 694 705 字尾陣列
每個子串一定是某個字尾的字首,那麼原問題等價於求所有字尾之間的不相同的字首的個數。如果所有的字尾按照 suffix sa 1 suffix sa 2 suffix sa 3 suffix sa n 的順序計算,不難發現,對於每一次新加進來的字尾 suffix sa k 它將產生 n sa k 1 個...
Spoj 1433 數字問題
題目大意 將 1 n 1 n 15 10 寫在紙上,然後在相鄰的數字間交替插入 和 求最後的 結果。例如當 n 為 12 時,答案為 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 5 解法分析 這是一道稍微複雜一點的數字計數問題。根據上述原則,我們首先探查數字確定,所有數字自由的情況。...
SPOJ 227 樹狀陣列
題意 給定乙個排列和陣列b i 表示i前面比a i 小的點的個數,求a i n的乙個排列 solution 維護乙個c陣列,表示c 從右向左對每個b i 找到最小的j 使c j b i 則a i j 如何維護c 樹狀陣列 如何查詢j 二分 include include include includ...