HDU 2485 Destroying the bus stations (IDA*+ BFS)

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2485


题意:给你n个点,m条相连的边,问你最少去掉几个点使从1到n最小路径>=k,其中不能去掉1,n两个点。

题解:这个题目可以用最小流解决,也可以用IDA*  +  BFS解决。


AC代码:

 

#include <iostream>

#include <cstdio>

#include <cstring>

#include <string>

#include <cstdlib>

#include <cmath>

#include <vector>

#include <list>

#include <deque>

#include <queue>

#include <iterator>

#include <stack>

#include <map>

#include <set>

#include <algorithm>

#include <cctype>

using namespace std;



#define si1(a) scanf("%d",&a)

#define si2(a,b) scanf("%d%d",&a,&b)

#define sd1(a) scanf("%lf",&a)

#define sd2(a,b) scanf("%lf%lf",&a,&b)

#define ss1(s)  scanf("%s",s)

#define pi1(a)    printf("%d\n",a)

#define pi2(a,b)  printf("%d %d\n",a,b)

#define mset(a,b)   memset(a,b,sizeof(a))

#define forb(i,a,b)   for(int i=a;i<b;i++)

#define ford(i,a,b)   for(int i=a;i<=b;i++)



typedef long long LL;

const int N=1005;

const int M=105;

const int INF=0x3f3f3f3f;

const double PI=acos(-1.0);

const double eps=1e-7;



int n,m,k;

int lin[N][N];//邻接表储存

int fa[N];//记录从1到n最短路径

bool vis[N];//标记节点是否被删除

int ans,Min;

bool flag;



struct xh

{

    int x,y,next;

}edge[N];



int bfs()

{

    int q[2222];

    int he=0,ta=0;

    mset(fa,-1);

    fa[1]=0;

    mset(q,0);

    q[ta++]=1;

    while(he!=ta)

    {

        int x=q[he++];

        for(int i=1;i<=lin[x][0];i++)

        {

            int v=lin[x][i];

            if(fa[v]==-1&&!vis[v])

            {

                fa[v]=x;

                q[ta++]=v;

                if(n==v)    return 1;

            }

        }

    }

    return 0;

}



void dfs(int dian,int depth)//求去掉最少个数点

{

    if(flag==false) return ;

    if(dian>depth) return ;



    int p=bfs();

    int sa[N]={0},t=0;

    if(p==0){flag=false;return;}

    for(int i=n;i!=1;i=fa[i])

    {

        sa[t++]=i;

        if(t>k){flag=false;return ;}

    }



    for(int i=1;i<t;i++)

    {

        int x=sa[i];

        if(vis[x])  continue;

        vis[x]=1;

        dfs(dian+1,depth);

        vis[x]=0;

        if(flag==false) return ;

    }

}



void IDA()

{

    if(n<=2)

    {

        puts("0");

        return ;

    }

    int depth=0;

    flag=true;

    vis[1]=1;

    while(flag)

    {

        dfs(0,depth);

        if(!flag)   break;

        depth++;

    }

    pi1(depth);

}



int main()

{

//    freopen("input.txt","r",stdin);

    while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k))

    {

        mset(lin,0);

        forb(i,0,m)

        {

            int a,b,t;

            si2(a,b);

            t=++lin[a][0];

            lin[a][t]=b;

            //这个地方写双向的就WA了,单向的就A了

        }

        IDA();

    }

    return 0;

}


 



超时代码:(IDA*  +  DFS)个人感觉应该差不多,但是就是超时了

 

#include <iostream>

#include <cstdio>

#include <cstring>

#include <string>

#include <cstdlib>

#include <cmath>

#include <vector>

#include <list>

#include <deque>

#include <queue>

#include <iterator>

#include <stack>

#include <map>

#include <set>

#include <algorithm>

#include <cctype>

using namespace std;



#define si1(a) scanf("%d",&a)

#define si2(a,b) scanf("%d%d",&a,&b)

#define sd1(a) scanf("%lf",&a)

#define sd2(a,b) scanf("%lf%lf",&a,&b)

#define ss1(s)  scanf("%s",s)

#define pi1(a)    printf("%d\n",a)

#define pi2(a,b)  printf("%d %d\n",a,b)

#define mset(a,b)   memset(a,b,sizeof(a))

#define forb(i,a,b)   for(int i=a;i<b;i++)

#define ford(i,a,b)   for(int i=a;i<=b;i++)



typedef long long LL;

const int N=1005;

const int M=105;

const int INF=0x3f3f3f3f;

const double PI=acos(-1.0);

const double eps=1e-7;



int n,m,k;

int lin[N][N];//邻接表储存

int cnt[M];//记录从1到n最短路径

bool vis[N];//标记节点是否被删除

int ans,Min;

bool flag;



struct xh

{

    int x,y,next;

}edge[N];



void dfs2(int k,int de)//求最短距离

{

    cnt[de]=k;//路径

    if(k==n)

    {

        Min=min(Min,de);

        return ;

    }



    for(int i=1;i<=lin[k][0];i++)

    {

        int t=lin[k][i];

        if(vis[t])  continue;

        vis[t]=1;

        dfs2(t,de+1);

        vis[t]=0;

    }

}



void dfs1(int dian,int depth)//求去掉最少个数点

{

    if(flag==false) return ;

    Min=INF;

    mset(cnt,0);

    dfs2(1,0);

//    cout<<"最短距离"<<Min<<endl;

//    cout<<"路径:";

//    if(Min!=INF)

//    {

//        for(int i=0;i<=Min;i++)

//            printf("%d ",cnt[i]);

//        cout<<endl;

//    }

//    system("pause");



    int xh=Min;

    if(xh>=k)

    {

        flag=false;

        ans=min(ans,dian);

        return ;

    }

    if(dian>=depth)

        return ;



    int sa[N];

    for(int i=0;i<=xh;i++)

        sa[i]=cnt[i];

    for(int i=1;i<xh;i++)

    {

        int t=sa[i];

        if(vis[t])  continue;

        vis[t]=1;

        dfs1(dian+1,depth);

        vis[t]=0;

        if(flag==false) return ;

    }

}



int main()

{

//    freopen("input.txt","r",stdin);

    while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k))

    {

        mset(lin,0);

        forb(i,0,m)

        {

            int a,b,t;

            si2(a,b);

            t=++lin[a][0];

            lin[a][t]=b;

            t=++lin[b][0];

            lin[b][t]=a;

        }

        ans=INF;

        mset(vis,0);

        vis[1]=1;

        flag=true;

        int depth=-1;

        while(flag)

        {

            depth++;

            dfs1(0,depth);

        }



        pi1(depth);

    }

    return 0;

}


 

 

你可能感兴趣的:(des)