BestCoder Round #74 (div.2 b) hdu5636 Shortest Path 【dfs】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5637

题意:有一条长度为nn的链. 节点ii和i+1i+1之间有长度为11的边. 现在又新加了3条边, 每条边长度都是1. 给出mm个询问, 每次询问两点之间的最短路.

分析:加了三条边,相当于六条边,每次从起点到终点跑个dfs就好了,裸的dfs复杂度为6!,可以发现经过一条边后就不会经过它的反向边,所以每次dfs复杂度6*4*2,总的复杂度48*10^6,加个剪枝就可以过了800+ms。

代码:


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 100010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int read() {
    char c=getchar();
    int re=0,f=1;
    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();}
    return re;
}
int x[6],y[6];
int vis[6];
int dt;
int ans;
void dfs(int dis,int pos) {
    if(pos==dt) {
        ans=min(dis,ans);
        return ;
    }
    dfs(dis+abs(dt-pos),dt);
    for(int i=0;i<=5;i++) {
        if(vis[i]) continue;
        vis[i]=1;
        vis[(i+3)%6]=1;
        if(dis+abs(pos-x[i])+1<ans)
            dfs(dis+abs(pos-x[i])+1,y[i]);
        vis[i]=0;
        vis[(i+3)%6]=0;
    }
}
int main() {
    int t=read();
    while(t--) {
        int n=read(),m=read();
        for(int i=0;i<=2;i++) {
            x[i]=read(),y[i]=read();
        }
        for(int i=3;i<=5;i++) {
            x[i]=y[i-3];
            y[i]=x[i-3];
        }
        ll sum=0;
        for(int i=1;i<=m;i++) {
            CLR(vis,0);
            int u=read(),v=read();
            if(u>v) swap(u,v);
            ans=v-u;dt=v;
            dfs(0,u);
            sum=(sum+((ll)ans*i)%mod)%mod;
        }
        printf("%I64d\n",sum);
    }
    return 0;
}


你可能感兴趣的:(BestCoder Round #74 (div.2 b) hdu5636 Shortest Path 【dfs】)