UVA 10048 - Audiophobia
2011-04-10 02:22
381 查看
题目大意:给出一个图,求某点到某点所必须忍受的最小噪音(即所经过路径的相邻两点的权的最大值最小)。
中文翻译
题目链接
题目类型:图论 / Floyd
题目分析:
①虽然做的是图论专题,但是开始还是觉得可以dp(后来证明我之前没有充分理解所谓“松弛技术”)。结果是写了一个可以过样例但是wa的dp。于是后来分析,关键点是两个相邻指标值,它们是相互依赖的,具体的说,假设有1点和2点它们相邻,则算d1的值时要根据d2的值算一次,但是d2的值也是要依赖d1的,所以这样解出来的不会是正确的结果。于是,我真正体会到了松弛技术(relax)的神奇之处。它可以把两个相互依赖的值慢慢收紧(得最小值)。
②Floyd。想到是Floyd的时候,算法便不难写出了。d[i][j]表示的是i点到j点要忍受的最小噪音,然后只需在松弛处稍作改动,把一般的 d[i][k]+d[k][j]换成max(d[i][k], d[k][j]),即d[i][j] = min(d[i][j], max(d[i][k], d[k][j])); 即可。
另外,“//if(d[i][k] < INF && d[k][j]<INF) //加这个判断,可以解决INF相加可能溢出的问题.” 本来需要的,但是现在不是相加而是求max,所以可以不用判断。
代码:
①
错误的dp,贴出来引以为戒。(= =)
②
Floyd
中文翻译
题目链接
题目类型:图论 / Floyd
题目分析:
①虽然做的是图论专题,但是开始还是觉得可以dp(后来证明我之前没有充分理解所谓“松弛技术”)。结果是写了一个可以过样例但是wa的dp。于是后来分析,关键点是两个相邻指标值,它们是相互依赖的,具体的说,假设有1点和2点它们相邻,则算d1的值时要根据d2的值算一次,但是d2的值也是要依赖d1的,所以这样解出来的不会是正确的结果。于是,我真正体会到了松弛技术(relax)的神奇之处。它可以把两个相互依赖的值慢慢收紧(得最小值)。
②Floyd。想到是Floyd的时候,算法便不难写出了。d[i][j]表示的是i点到j点要忍受的最小噪音,然后只需在松弛处稍作改动,把一般的 d[i][k]+d[k][j]换成max(d[i][k], d[k][j]),即d[i][j] = min(d[i][j], max(d[i][k], d[k][j])); 即可。
另外,“//if(d[i][k] < INF && d[k][j]<INF) //加这个判断,可以解决INF相加可能溢出的问题.” 本来需要的,但是现在不是相加而是求max,所以可以不用判断。
代码:
①
错误的dp,贴出来引以为戒。(= =)
]#include<cstdio> #include<cstring> #include<vector> using namespace std; #define MAXN 102 //点 #define INF 1<<30 //#define MAXM 1002//边 vector<int> G[MAXN]; int w[MAXN][MAXN]; int d[MAXN], vis[MAXN]; inline int max(int x, int y) {return x>y? x: y;} inline int min(int x, int y) {return x<y? x: y;} int st, en; int dp(int cur) { if(cur == st) return 0; //停止条件 if(vis[cur] == 1) return d[cur]; vis[cur] = -1; //正在访问 int ans = INF; for(int i=0; i<(int)G[cur].size(); i++) { int u = cur, v = G[cur][i]; if(vis[v] == -1) continue; //正在访问的不扩展 int t = max(dp(v), w[u][v]); ans = min(t, ans); } vis[cur] = 1; return d[cur] = ans; //若ans最后还为INF,表示无法到达 } int c, s, q; //点,边,起终点对数 void clear() { for(int i=1; i<=c; i++) if(!G[i].empty()) G[i].clear(); } int read_graph() { int ok=1; scanf("%d%d%d", &c, &s, &q); if(!c && !s && !q) return 0; for(int i=0; i<s; i++) { int c1, c2, di; scanf("%d%d%d", &c1, &c2, &di); G[c1].push_back(c2); G[c2].push_back(c1); w[c1][c2] = w[c2][c1] = di; } return 1; } int main() { int T=1; while(read_graph()) { if(T != 1) printf(" /n"); //case间 空行 //!各組測試資料間請輸出一空白列 printf("Case #%d/n", T++); for(int i=0; i<q; i++) { memset(vis, 0, sizeof(vis)); scanf("%d%d", &st, &en); int t = dp(en); if(t == INF) printf("no path/n"); else printf("%d/n", t); // } clear(); } }
②
Floyd
]#include<cstdio> #include<cstring> using namespace std; #define MAXN 102 //点 #define INF 1<<30 int d[MAXN][MAXN]; //!! inline int max(int x, int y) {return x>y? x: y;} inline int min(int x, int y) {return x<y? x: y;} int st, en; int c, s, q; //点,边,起终点对数 void floyd() { for(int k=1; k<=c; k++) for(int i=1; i<=c; i++) for(int j=1; j<=c; j++) //if(d[i][k] < INF && d[k][j]<INF) //加这个判断,可以解决INF相加可能溢出的问题 d[i][j] = min(d[i][j], max(d[i][k], d[k][j])); //!! } int read_graph() { scanf("%d%d%d", &c, &s, &q); if(!c && !s && !q) return 0; for(int i=1; i<=c; i++) for(int j=1; j<=c; j++) d[i][j] = i == j? 0: INF; for(int i=0; i<s; i++) { int c1, c2, di; scanf("%d%d%d", &c1, &c2, &di); d[c1][c2] = d[c2][c1] = di; } return 1; } int main() { int T=1; while(read_graph()) { if(T != 1) printf("/n"); //case间 空行 printf("Case #%d/n", T++); floyd(); for(int i=0; i<q; i++) { scanf("%d%d", &st, &en); int t = d[st][en]; if(t == INF) printf("no path/n"); else printf("%d/n", t); } } }
相关文章推荐
- UVA10048 Audiophobia[Floyd变形]
- UVa 10048 Audiophobia(最短路&Floyd)
- UVa 10048 Audiophobia 最短路的最大值
- UVA 10048 Audiophobia
- UVA - 10048 Audiophobia
- UVa10048_Audiophobia(最短路/floyd)(小白书图论专题)
- UVa10048 Audiophobia (Floyd)
- UVA10048-Audiophobia-最短路
- UVA 10048 Audiophobia 最小生成树
- uva 10048 Audiophobia
- uva10048 - Audiophobia
- UVa 10048 Audiophobia
- UVa 10048: Audiophobia
- UVA 10048 Audiophobia
- UVA10048-Audiophobia
- uva 10048 Audiophobia(最小生成树)
- uva 10048 Audiophobia(最小生成树)
- UVa 10048: Audiophobia
- UVa10048_Audiophobia(最短路/floyd)(小白书图论专题)
- 例题11-5 UVA - 10048 Audiophobia 噪音恐惧症(Floyd算法)