hdu_1245 spfa+标记

来源:互联网 发布:juniper pulse mac 编辑:程序博客网 时间:2024/05/29 19:21

建图O(n2),spfa O(2e)~~ok ac! so easy~

#include<iostream>#include<iomanip>#include<vector>#include<string>#include<algorithm>#include<cmath>#include<queue>using namespace std;const int maxn=111;const int e=50;const double oo=10e9;const double eps=1e-8;const int inf=0x7fffffff;struct zz{    int x;    int y;}z[maxn];struct z2{    double len;    int from;    int to;}t2;int tx,ty,n,d,now,temp,minstep;int step[maxn];bool can[maxn];bool vis[maxn];double go[maxn];double way[maxn];vector<z2>v[maxn];double td,dd,minway,tmin;queue<int>q;void init(){    for(int i=0;i<=n;i++)    {        v[i].clear();    }    memset(can,false,sizeof(can));    memset(step,0,sizeof(step));    for(int i=1;i<=n;i++)    {        way[i]=oo;    }    way[0]=0;    return ;}bool get(int a){    if(abs(z[a].x-100) <= d || abs(z[a].x) <= d || abs(z[a].y) <= d || abs(z[a].y-100) <= d )    {        go[a]=min( min( abs(z[a].x-100) , abs(z[a].x) ) , min( abs(z[a].y) , abs(z[a].y-100) ) );        return true;    }    else    {        return false;    }}bool yes(int a,int b,double cmp=d){    td=sqrt(double( (z[b].y-z[a].y)*(z[b].y-z[a].y) + (z[b].x-z[a].x)*(z[b].x-z[a].x) ) );    if( td - eps < cmp)    {        t2.len=td;        return true;    }    else    {        return false;    }}void build(){    for(int i=1;i<=n;i++)    {        if( yes ( 0, i, d+7.5) )        {            t2.from=0;            t2.to=i;            v[0].push_back(t2);        }        if(get(i))        {            can[i]=true;        }    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(j==i)            {                continue;            }            if( yes( i, j) )            {                t2.from=i;                t2.to=j;                v[i].push_back(t2);            }        }    }    return ;}void spfa(){    memset(vis,false,sizeof(vis));    while(!q.empty())    {        q.pop();    }    step[0]=0;    q.push(0);    vis[0]=true;    while(!q.empty())    {        now=q.front();        q.pop();        for(int i=0;i<v[now].size();i++)        {            dd = way[now] + v[now][i].len;            temp = v[now][i].to;            if( dd == way[temp] )            {                if( step[temp] > step[now] + 1 )                {                    step[temp] = step[now] + 1;                    if(!vis[temp])                    {                        q.push(temp);                        vis[temp]=true;                    }                    continue;                }            }            else if( dd < way[temp] )            {                way[temp] = dd;                step[temp] = step[now] + 1;                if(!vis[temp])                {                    q.push(temp);                    vis[temp]=true;                }                continue;            }        }        vis[now]=false;    }    return ;}bool judge(){    bool re=false;    for(int i=1;i<=n;i++)    {        if(!can[i])        {            continue;        }        else        {            if(way[i]!=oo)            {                way[i]+=go[i];                re=true;            }            else            {                can[i]=false;            }        }    }    if(!re)    {        return false;    }    minway=oo;    minstep=inf;    for(int i=1;i<=n;i++)    {        if(!can[i])        {            continue;        }        if(way[i]==minway)        {            if(step[i]<minstep)            {                minstep=step[i];            }        }        else if(way[i]<minway)        {            minway=way[i];            minstep=step[i];        }    }    minway-=7.5;    minstep++;    return true;}int main(){    z[0].x=50;    z[0].y=50;    cout.setf(ios::fixed);    while(cin>>n>>d)    {        init();        for(int i=1;i<=n;i++)        {            cin>>z[i].x>>z[i].y;            z[i].x+=e;            z[i].y+=e;        }        build();        spfa();        if(judge())        {            cout<<setprecision(2)<<minway<<" "<<minstep<<endl;        }        else        {            cout<<"can't be saved"<<endl;        }    }    return 0;}