hdu 4435 charge-station

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;

}

 

 

你可能感兴趣的:(char)