POJ Contest - ACM Trainning

Problem B: Robot Challenge


 dp水题,状态很容易想到,dp[ i ] 表示机器人到达第i个点的最小花费,然后O(n)的时间状态转移


poj Problem H: Ideal Path


这个纠结很久的题目终于ac了,蛋疼无限呀!!!

肯定有比我好的方法,我是纪录每个节点的前两种颜色,然后对于每一层开始排序,然后再重新分配大小关系……感觉好麻烦,肯定有比我好的方法,感觉我这个方法实在是太土了


B题代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

using namespace std;

const int inf=0x3fffffff;
const int maxn=1010;
double dp[maxn],sum[maxn],x[maxn],y[maxn],p[maxn];
double dis[maxn][maxn];

int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        for(int i=1;i<=n;i++)
          scanf("%lf%lf%lf",&x[i],&y[i],&p[i]),sum[i]=sum[i-1]+p[i];
        x[n+1]=100;
        y[n+1]=100;
        p[0]=0;
        sum[n+1]=sum[n];
        n++;
        for(int i=0;i<=n;i++)
        for(int j=i+1;j<=n;j++)
          dis[i][j]=sqrt((x[j]-x[i])*1.0*(x[j]-x[i])+(y[j]-y[i])*1.0*(y[j]-y[i]));

        fill(dp,dp+n+1,inf);
        dp[0]=0;
        //cout<<dis[0][1]<<endl;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<i;j++)
              dp[i]=min(dp[i],dp[j]+sum[i-1]-sum[j]+1.0+dis[j][i]);
        }
        printf("%.3lf\n",dp[n]);
    }
    return 0;
}

H题代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <queue>

using namespace std;

const int maxn=500010;
const int maxe=1000010;
const int inf=0x3fffffff;

int var[maxe],next[maxe];
int col[maxe];
int h[maxn],dp[maxn],tot,n,m,tmp[maxn],pre[maxn],from[maxn],val[maxn];
bool vis[maxn];
long long ss[maxn][2];
int que[5000010];

void add(int u,int v,int c)
{
    from[tot]=u,var[tot]=v,col[tot]=c,next[tot]=h[u],h[u]=tot++;
}

int cmp(int a,int b,int c,int d)
{
    if(a>c) return 0;
    if(a==c&&b>=d) return 0;
    return 1;
}
int cmp1(int a,int b)
{
    return !cmp(ss[b][0],ss[b][1],ss[a][0],ss[a][1]);
}
bool equal(int a,int b)
{
    return ss[a][0]==ss[b][0]&&ss[a][1]==ss[b][1];
}
void bfs()
{
    memset(vis,0,sizeof(vis));
    dp[1]=0;
    ss[1][0]=0;
    int next_level=1,l=0,r=0;
    que[r++]=1;
    pre[1]=0;
    while(l<r)
    {
        int cur=que[l];
        vis[cur]=1;

        if(dp[cur]==next_level)
        {
            int num=0;
            for(int i=l;i<r;i++) tmp[num++]=que[i];
            sort(tmp,tmp+num,cmp1);

            int cnt=1;
            val[0]=1;
            for(int i=1;i<num;i++)
              if(equal(tmp[i-1],tmp[i])) val[i]=cnt;
              else val[i]=++cnt;

            for(int i=0;i<num;i++)
              ss[tmp[i]][0]=val[i],ss[tmp[i]][1]=0;
            next_level++;
        }
        l++;
        for(int i=h[cur];i!=-1;i=next[i])
        {
            int v=var[i];
            if(dp[v]>dp[cur]+1||((dp[v]==dp[cur]+1)&&cmp(ss[cur][0],col[i],ss[v][0],ss[v][1])))
            {
                dp[v]=dp[cur]+1;
                ss[v][0]=ss[cur][0];
                ss[v][1]=col[i];
                pre[v]=i;
                if(!vis[v]) vis[v]=1,que[r++]=v;
            }
        }
    }
}
int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&m)==2)
    {
        tot=0;
        memset(h,-1,sizeof(h));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        fill(dp,dp+n+1,inf);
        bfs();
        int sz=dp[n];
        printf("%d\n",sz);
        vector<int> path;
        int nw=n;
        for(int i=0;i<sz;i++)
        {
            nw=pre[nw];
            path.push_back(col[nw]);
            nw=from[nw];
        }
        printf("%d",path[sz-1]);
        for(int i=sz-2;i>=0;i--)
           printf(" %d",path[i]);
        puts("");
    }
    return 0;
}



你可能感兴趣的:(POJ Contest - ACM Trainning)