poj1129 poj1106

来源:互联网 发布:js窗口高度 编辑:程序博客网 时间:2024/05/17 17:58


poj1129

算法思想:DFS, 回溯法, 子集树,四色定理

初始认为只需一种颜色(色数为1),当颜色数不能满足涂色要求时,就再添加一种颜色(色数加1)

bool OK(int id, int c) 用于判断颜色c是否可以给点id着色


//poj1129 图的染色问题,DFS,子集树 #include <iostream>#include <cstring>#include <string>using namespace std;const int maxn = 128;bool pic[maxn][maxn], finished;int n, color[maxn], ans;bool OK(int id, int c) {for (int i = 'A'; i < n; ++i) {if(pic[id][i] && c == color[i]) //两点相邻,且颜色相同,kill return false; }return true;}void DFS(int id, int total) {if (finished) {return;}if (id >= n || ans >= 4) { //四色定理用于减枝 finished = true;return;}for (int i = 1; i <= total; ++i) { //为第id个点,选择第i种颜色 if (OK(id, i)) {color[id] = i;DFS(id + 1, total);color[id] = 0; //这里没有用那个图论中着色的算法(忘了名字),用的回溯法}}if (!finished) { //total种颜色无法完成染色任务,在加一种颜色 ans++;DFS(id, total + 1);}}int main(){while((cin >> n) && n) {memset(pic, 0, sizeof(bool) * maxn * maxn);for (int i = 0; i < n; ++i) {string str;cin >> str;for (int i = 2; i < str.length(); ++i) {pic[str[0]][str[i]] = pic[str[i]][str[0]] = true;}} //无向图已构建好,下面对图进行着色(四色定理用于减枝)ans = 1;n += 'A';finished = false;DFS('A', 1);cout << ans;if (ans == 1) {cout << " channel needed." << endl;}else {cout << " channels needed." << endl;}} return 0;}


poj1160

动态规划

#include <cstdio> #include <algorithm>#define INF 0x3f3f3f3f#define N 35const int maxn = 307;int dp[maxn][N], dis[maxn][maxn];  int x[maxn];int main(){int v, p;while(~scanf("%d%d", &v, &p)) {for (int i = 1; i <= v; ++i) {scanf("%d", x + i);}for (int i = 1; i <= v; ++i) {dis[i][i] = 0;//dis[i][j]表示在第i个村庄和第j个村庄建建立一个邮局的最短距离 for (int j = i + 1; j <= v; ++j)dis[i][j] = dis[i][j - 1] + x[j] - x[(i + j) >> 1];dp[i][i] = 0; // i个村长i个邮局 dp[i][1] = dis[1][i]; //前i个村庄建立一个邮局 } for (int j = 2; j <= p; ++j) { //dp[i][j]表示前i个村庄建立j个邮局的所求最短距离for (int i = j + 1; i <= v; ++i) { //前i个村庄 dp[i][j] = INF;for (int k = j - 1; k < i; ++k) { //j - 1 < k < idp[i][j] = std::min(dp[i][j], dp[k][j - 1] + dis[k + 1][i]); }}}printf("%d\n", dp[v][p]);}return 0;}


原创粉丝点击