HDU 1599 find the mincost route 、 poj 1734 Sightseeing trip

来源:互联网 发布:php源码学习 编辑:程序博客网 时间:2024/05/10 22:42

今天无向图求最小环的算法,重温了一遍floyd。

首先对于floyd算法,是一种动态规划的思想

dp[k][i][j]代表的含义是从ui到uj经过的除端点以外最大的不超过k的点的最小值

dp[k][i][j] = min(dp[k - 1][i][k] + dp[k - 1][k][j],dp[k][i][j]);

而求floyd时可以顺便求得最小环,对于构成最小环的点集{x1, x2, ...,xk},其中必定存

一个最大点xk,那么最小环的长度可以由 dp[i][j]+dis[j][xk]+dis[xk][i]来表

示,其中i,j均在点集中且小于xk,dp[i][j]是i到j的最短路径(且最大经过的点为xk 

-1)。对于每一个xk,枚举所有的dp[i][j](0 <= i , j <= xk-1)。便可求的最小环。


HDU 1599 find the mincost route 

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define MAXN 105#define INF 0x1f1f1f1fint dp[MAXN][MAXN],w[MAXN][MAXN],n,m;int floyd(){    int ans = INF;    for(int k = 1;k <= n;k++)    {        for(int i = 1;i < k;i++)            for(int j = 1 + i;j < k;j++)                ans = min(ans,dp[i][j] + w[i][k] + w[k][j]);        for(int i = 1;i <= n;i++)            for(int j = 1;j <= n;j++)                dp[i][j] = min(dp[i][k] + dp[k][j],dp[i][j]);    }    return ans;}int main(){    int u,v,val;    while(scanf("%d%d",&n,&m) != EOF)    {        memset(dp,0x1f,sizeof(dp));        memset(w,0x1f,sizeof(w));        while(m--)        {            scanf("%d%d%d",&u,&v,&val);            dp[u][u] = dp[v][v] = w[u][u] = w[v][v] = 0;            w[v][u] = w[u][v] = dp[u][v] = dp[v][u] = min(val,dp[u][v]);        }        int ans = floyd();        if(ans == INF)puts("It's impossible.");        else printf("%d\n",ans);    }}

poj 1734 Sightseeing trip

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define MAXN 105#define INF 0x1f1f1f1fint dp[MAXN][MAXN],w[MAXN][MAXN],pre[MAXN][MAXN],arr[MAXN];int n,m,len;void dfs(int i,int j){    int k = pre[i][j];    if(k == -1)    {        arr[len++] = i;        return;    }    dfs(i,k),dfs(k,j);}void floyd(){    int ans = INF;    len = 0;    for(int k = 1;k <= n;k++)    {        for(int i = 1;i < k;i++)            for(int j = 1 + i;j < k;j++)            {                int cur = dp[i][j] + w[i][k] + w[k][j];                if(cur < ans)                {                    ans = cur;                    len = 0;                    arr[len++] = k;                    dfs(i,j);                    arr[len++] = j;                }            }        for(int i = 1;i <= n;i++)            for(int j = 1;j <= n;j++)            {                if(dp[i][j] > dp[i][k] + dp[k][j])                {                    dp[i][j] = dp[i][k] + dp[k][j];                    pre[i][j] = k;                }            }    }}int main(){    int u,v,val;    while(scanf("%d%d",&n,&m) != EOF)    {        memset(dp,0x1f,sizeof(dp));        memset(w,0x1f,sizeof(w));        memset(pre,-1,sizeof(pre));        while(m--)        {            scanf("%d%d%d",&u,&v,&val);            dp[u][u] = dp[v][v] = w[u][u] = w[v][v] = 0;            w[v][u] = w[u][v] = dp[u][v] = dp[v][u] = min(val,dp[u][v]);        }        floyd();        if(len < 2)puts("No solution.");        else            for(int i = 0;i < len;i++)                if(i != len - 1)printf("%d ",arr[i]);                else printf("%d\n",arr[i]);    }}



0 0
原创粉丝点击