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;
}
浙公网安备 33010602011771号