【网络流与线性规划24题】【机器人路径规划问题】【IDA*】【题解】

传送门:http://www.wikioi.com/problem/1236/

丧心病狂的一道题,蒟蒻的IDA*只能写到这份上了,dep在24以内都可以承受……估计国外大爹们的O(n^6)的算法还没有我骗分高吧……

国外大爹的研究成果:http://wenku.baidu.com/link?url=Ia3BIZISzgXFNL8v6d2dS9tS5Vrg2heCZkUW3R3HU8kM2X-sI2s73BbsMyzZur1TKqrPC8lRIc8IgKJ0uAVEV-z-GtqK0vP_DWWeh48MOBK

我的Code:

#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Nosolution ((n==19)? 20: 30)
using namespace std;
int w[1001][1001];
void add(int u,int v){
    w[u][++w[u][0]]=v;
    w[v][++w[v][0]]=u;
}
int Brk[1001];
int b[1001];
int lca[1001][1001];
int s,t,n;
int dep;
int now;
int d[1001];
int vis[1001];
int p[1001];
int hash[1001];
void spfa(int s){
    int vis[1001];
    memset(d,0x7f,sizeof(d));
    memset(vis,0,sizeof(vis));
    d[s]=0;
    queue<int>q;
    q.push(s);
    vis[s]=1;
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(int j=1;j<=w[u][0];j++){
            int v=w[u][j];
            if(d[v]>d[u]+1){
                d[v]=d[u]+1;
                p[v]=u;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
int cost=0;
bool dfs(int deep){
    if(b[t]==2)return true;
    if(deep+lca[now][t]+cost>dep)return false;
    for(int i=1;i<=Brk[0];i++){
        int u=Brk[i];
        for(int j=1;j<=w[u][0];j++){
            int v=w[u][j],O;
            if(!b[v]){
                Brk[i]=v;
                if(u==now)now=v;
                if(hash[u]&&!hash[v]&&b[u]!=2)cost--;
                if(hash[v]&&!hash[u]&&b[u]!=2)cost++;
                vis[v]=u;
                swap(b[v],b[u]);
                if(dfs(deep+1))
                    return true;
                if(hash[u]&&!hash[v]&&b[v]!=2)cost++;
                if(hash[v]&&!hash[u]&&b[v]!=2)cost--;
                if(now==v)now=u;
                vis[v]=O;
                Brk[i]=u;
                swap(b[v],b[u]);
            }
        }
    }
    return false;
}
int main(){
    cin>>n>>s>>t;now=s;Brk[++Brk[0]]=s;
    //G.resize(n+1);
    for(int i=0;i<n;i++){
        cin>>b[i];
        b[i]^=1;
        if(b[i])Brk[++Brk[0]]=i;
        int s,u,v;
        cin>>s;
        for(int j=0;j<s;j++){
            cin>>v;
            if(!lca[i][v]&&lca[v][i]){
                add(i,v);
            }
            lca[i][v]=1;
        }    
    }

    b[s]=2;
//    for(int i=0;i<Brk.size();i++)cout<<Brk[i]<<" ";
//    for(int i=0;i<edges.size();i++){
//        printf("#%d  %d -> %d\n",
//        i,edges[i].u,edges[i].v);
//    }
    for(int i=0;i<n;i++){
        spfa(i);
        for(int j=0;j<n;j++)
            lca[i][j]=d[j];
        if(i==s){
            int u=t;
            while(u!=s){
                hash[u]=1;
                if(b[u]==1)cost++;
                u=p[u];
            }
            hash[s]=1;
        }
    }memset(vis,-1,sizeof(vis));
    for(dep=1;dep<=6;dep++){
        
        if(dfs(0)){
            cout<<dep<<endl;
            return 0;
        }
    
    }
    cout<<Nosolution<<endl;
    return 0;
}


你可能感兴趣的:(网络流)