http://acm.hdu.edu.cn/showproblem.php?pid=4435

有题意可以知道 对应第k个城市 即使前(k-1)个城市都建立加油站 也没有在第k个城市建立加油站花的钱多

思路 :

如果全部都建立加油站 还是不能满足条件的话 则说明没有解决方案

否则 从后面逐个向前尝试看是否可以不建立

对于 是否能达到目的 我用的方法比较麻烦

两次 spfa 分别求到某个城市时 还未在此站加油(也可能没有加油站)最多可以有多少油 和 在某个城市想回来的话最少需要的油量

每个点必须满足 有的油量可以回来

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<iomanip>
using namespace std;

#define LL long long
const int INF=0x5fffffff;
const double FINF=1e9;
const int N=205;
int d[N][N];
int x[N];
int y[N];
int dist[N];
int need[N];
int had[N];
bool in[N];
void spfa1(int s,int n,int k)
{
    queue<int>qt;
    memset(in,false,sizeof(in));
    for(int i=1;i<=n;++i)
    dist[i]=-1;
    dist[s]=0;
    in[s]=true;
    qt.push(s);
    while(!qt.empty())
    {
        int x=qt.front();
        qt.pop();
        in[x]=false;
        for(int i=1;i<=n;++i)
        {
            if(i==s||i==x||d[x][i]>min(dist[x]+had[x],k))
            continue;
            int tmp=min(dist[x]+had[x],k)-d[x][i];
            if(dist[i]<tmp)
            {
                dist[i]=tmp;
                if(!in[i])
                {
                    in[i]=true;
                    qt.push(i);
                }
            }
        }
    }
}
void spfa2(int s,int n,int k)
{
    queue<int>qt;
    memset(in,false,sizeof(in));
    for(int i=1;i<=n;++i)
    need[i]=INF;
    need[s]=0;
    in[s]=true;
    qt.push(s);
    while(!qt.empty())
    {
        int x=qt.front();
        qt.pop();
        in[x]=false;
        for(int i=1;i<=n;++i)
        {
            if(d[x][i]+need[x]>k)
            continue;
            int tmp=need[x]+d[x][i];
            tmp=tmp-had[i];
            if(tmp<0)
            tmp=0;
            if(need[i]>tmp)
            {
                need[i]=tmp;
                if(!in[i])
                {
                    in[i]=true;
                    qt.push(i);
                }
            }
        }
    }
}
bool Can(int n,int k)
{
    spfa1(1,n,k);
    spfa2(1,n,k);
    for(int i=1;i<=n;++i)
    {
        if(need[i]>dist[i])
        return false;
    }
    return true;
}
int main()
{
    //freopen("data.txt","r",stdin);
    int n,k;
    while(scanf("%d %d",&n,&k)!=EOF)
    {
        for(int i=1;i<=n;++i)
        {
            scanf("%d %d",&x[i],&y[i]);
            for(int j=1;j<i;++j)
            {
                d[i][j]=d[j][i]=ceil(sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
            }
        }
        for(int i=1;i<=n;++i)
        had[i]=k;
        if(!Can(n,k))
        {printf("-1\n");continue;}
        int ans[N];
        memset(ans,0,sizeof(ans));
        ans[1]=1;
        for(int i=n;i>1;--i)
        {
            had[i]=0;
            if(!Can(n,k))
            {had[i]=k;ans[i]=1;}
        }
        int i=n;
        while(!ans[i])
        --i;
        for(int l=i;l>=1;--l)
        printf("%d",ans[l]);
        printf("\n");
    }
    return 0;
}

 

 

posted on 2012-11-02 18:54  夜->  阅读(147)  评论(0编辑  收藏  举报