zoukankan      html  css  js  c++  java
  • poj1734 Sightseeing trip[最小环]

    一个最小环裸题。最小环的两种求法dijkstra和Floyd直接参见这里我就是从这里学的,不想写了。

    注意这里最重要的一个点是利用了Floyd的dp过程中路径上点不超过$k$这一性质,来枚举环上最大编号并枚举连边,这样另外枚举的两个点的最短路肯定不会经过和$k$连的边。

    坑点:

    • 平常inf都开0x3f3f3f3f,这题没注意,在求环那里如果三个inf一加,就爆掉了。。所以要改小一点。这个问题值得重视。
    • Floyd正常输出路径应该就更新的时候记录中间点,最后直接递归输出。但是这里因为记录路径中$x$和$y$间的最短路必须是不经过当时的大于等于$k$的点的,所以最小环答案更新即记路径,不能到最后用Floyd转移数组输出路径。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define dbg(x) cerr << #x << " = " << x <<endl
     7 using namespace std;
     8 typedef long long ll;
     9 typedef double db;
    10 typedef pair<int,int> pii;
    11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    16 template<typename T>inline T read(T&x){
    17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    19 }
    20 const int N=100+5,INF=0x0f0f0f0f;
    21 int mp[N][N],dis[N][N],g[N][N],h[N][N],n,m,ans=INF,pt1,pt2,pt3;
    22 void print(int i,int j){
    23     if(!h[i][j]){printf("%d ",i);return;}
    24     print(i,h[i][j]);
    25     print(h[i][j],j);
    26 }
    27 void path(int i,int j){
    28     h[i][j]=g[i][j];
    29     if(!g[i][j])return;
    30     path(i,g[i][j]),path(g[i][j],j);
    31 }
    32 
    33 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    34     memset(mp,0x0f,sizeof mp),memset(dis,0x0f,sizeof dis);
    35     read(n),read(m);
    36     for(register int i=1,x,y,z;i<=m;++i)read(x),read(y),read(z),dis[x][y]=dis[y][x]=mp[y][x]=mp[x][y]=_min(mp[x][y],z);
    37     for(register int i=1;i<=n;++i)dis[i][i]=mp[i][i]=0;
    38     for(register int k=1;k<=n;++k){
    39         for(register int i=1;i<k;++i)
    40             for(register int j=i+1;j<k;++j)
    41                 if(MIN(ans,mp[i][k]+mp[j][k]+dis[i][j]))
    42                     pt1=i,pt2=j,pt3=k,path(i,j);//dbg(i),dbg(j),dbg(k);
    43         for(register int i=1;i<=n;++i)
    44             for(register int j=1;j<=n;++j)
    45                 if(MIN(dis[i][j],dis[i][k]+dis[k][j]))
    46                     g[i][j]=k;
    47     }
    48     if(ans<INF)print(pt1,pt2),printf("%d %d
    ",pt2,pt3);
    49     else puts("No solution.");
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    [LeetCode#91]Decode Ways
    [LeetCode#130]Surrounded Regions
    [LeetCode#84]Largest Rectangle in Histogram
    [LeetCode#179]Largest Number
    [LeetCode#187]Repeated DNA Sequences
    [LeetCode#200]Number of Islands
    [LeetCode#268]Missing Number
    [LeetCode#44]Wildcard Matching
    [LeetCode#128]Longest Consecutive Sequence
    1如何给devexpress的gridview控件绘制全选按钮
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11595758.html
Copyright © 2011-2022 走看看