hdu 2437 深搜

题意:n个点(n<=1000),m条有向边(m<=20000),起点s,有的点是P类型,有的点是T类型,求最短的到达P型点的路线,要求路径长度能被k整除(k<=1000),输出长度和终点编号。若有多条,输出终点编号最小的。

分析:一开始看点很多,又能重复走,觉得深搜爆栈,所以广搜,果断爆空间。。

后来深搜,若有两个长度d1,d2模k余数相同,只保留较小的那个。

 

 

const int N = 1005, M = 20005;
int n, m, s, p, ansv;
LL k, ansd;

int head[N];
char c[N];

struct nod{
    int v, next; LL d;
}E[M];

LL mp[N][N];

void read(){
    ansd = -1; ansv = -1;
    scanf("%d%d%d%I64d", &n, &m, &s, &k);
    scanf("%s", c+1);
    memset(mp, -1, sizeof mp);
    memset(head, -1, sizeof head);
    int u, v; LL d;   p = 0;
    FOR(i, 0, m) {
        scanf("%d%d%I64d", &u, &v, &d);
        E[p].d=d; E[p].v=v; E[p].next=head[u]; head[u]=p++;
    }
}

void dfs(int u, LL d){
    if(ansd!=-1 && d>ansd) return;
    if(c[u]=='P' && d%k==0) {
        if(ansd==-1 || d<ansd){
            ansd = d; ansv = u; return;
        }else if(d == ansd && u<ansv) ansv=u;
    }
    for(int j = head[u]; j != -1; j = E[j].next){
        int v = E[j].v; LL dd = d + E[j].d;
        int mod = dd % k;
        if(mp[v][mod]!=-1 && mp[v][mod]<=dd) continue;
        mp[v][mod] = dd;
        dfs(v, dd);
    }
}

int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    #endif

    int T; scanf("%d", &T);
    FOE(t, 1, T){
        read();
        dfs(s, 0);
        printf("Case %d: %I64d %d\n", t, ansd, ansv);
    }

    return 0;
}

 

posted @ 2013-05-27 22:12  心向往之  阅读(411)  评论(0编辑  收藏  举报