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; }