POJ-2531 Network Saboteur 枚举||随机化
生活随笔
收集整理的這篇文章主要介紹了
POJ-2531 Network Saboteur 枚举||随机化
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:給定一個完全圖,現(xiàn)在要求將這個圖劃分成兩個部分,求兩個部分的點做笛卡爾積之后的點對的距離和最大值是多少。
解法一:由于給定的點最多只有20個,所以直接2^N*O(n)的時間復(fù)雜度枚舉即可。
解法二:采用隨機化算法,枚舉某一個點,將這個點所屬于的集合進行翻滾。
代碼如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> using namespace std;int N, G[25][25];int cal(int x) {int A[25], B[25], ca = 0, cb = 0, ret = 0;for (int i = 0; i < N; ++i) {if (x & (1 << i)) {A[ca++] = i + 1;} else {B[cb++] = i + 1; }}for (int i = 0; i < ca; ++i) {for (int j = 0; j < cb; ++j) {ret += G[A[i]][B[j]];} }return ret; }int main() {int ret;while (scanf("%d", &N) == 1) {ret = 0;for (int i = 1; i <= N; ++i) {for (int j = 1; j <= N; ++j) {scanf("%d", &G[i][j]);}} // 對給定信息進行存儲int mask = (1 << N) - 1;for (int i = 1; i < mask; ++i) {ret = max(ret, cal(i));}printf("%d\n", ret);}return 0; }下面這個隨機化代碼G++過不了,不知道為什么。
#include <cstdlib> #include <cstdio> #include <cstring> #include <iostream> #include <ctime> #include <map> using namespace std; // 由于問題的規(guī)模相對較小 // 可以使用隨機化算法來解決這個問題 int N, G[30][30];int randtime = 200000;int A[30];void MoveAToB(int x, int &t) {A[x] = 0;for (int i = 1; i <= N; ++i) {if (A[i]) t += G[x][i];else t -= G[x][i];} }void MoveBToA(int x, int &t) {A[x] = 1;for (int i = 1; i <= N; ++i) {if (!A[i]) t += G[x][i];else t -= G[x][i];} }int randpro() {int rd, ret = 0, t = 0;for (int i = 0; i < randtime; ++i) {rd = rand() % N + 1; // 得到一個點,這個點被if (A[rd]) { // 說明在A集合 MoveAToB(rd, t);} else { // 說明在B集合 MoveBToA(rd, t);}ret = max(ret, t);}return ret; }int main() {srand(time(NULL));while (scanf("%d", &N) == 1) {for (int i = 1; i <= N; ++i) {for (int j = 1; j <= N; ++j) {scanf("%d", &G[i][j]);}}for (int i = 1; i <= N; ++i) {A[i] = 1; // 先假設(shè)所有的元素都是屬于第一個集合 }printf("%d\n", randpro());} return 0; }?
?
轉(zhuǎn)載于:https://www.cnblogs.com/Lyush/archive/2012/11/19/2777998.html
總結(jié)
以上是生活随笔為你收集整理的POJ-2531 Network Saboteur 枚举||随机化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android app项目开发步骤总结
- 下一篇: 算法题集-2