posts - 43,  comments - 9,  trackbacks - 0

最近做了两道floyd变种的题目,又加深了对floyd原理的理解.

第2题: tju 3214 Find the Path
http://acm.tju.edu.cn/toj/showp3214.html

题目大意是给一个无向图,每个结点有个点权c[p]
对于查询的点对i,j和权k,求在中间节点(不包含端点i,j)权值不大于k的限制下,i,j间最短路径.
由于查询次数多,因此一次查询复杂度需要在O(logn)以内.考虑计算出所有点对在所有限制条件下的最短路,O(1)查询.
限制条件不作用于端点i,j,正好可以用floyd解决.因为floyd正是不断向中间点集中加入点.只要限制一下这些被加入点的条件,就可以解决这题了.
初步归纳,对于查询i,j,k,应该输出将所有c[p]<=k的点加入后的floyd[i,j]
对于限制k,点集的情况是:加了权最小的m个(0<=m<=N),这些点的权都不超过k
因此将点按权值升序排列.dist[k][i][j]表示:前k个点被加入后,i,j间的最短路.

代码如下:
 

 1#include <iostream>
 2using namespace std;
 3int T,N,M,Q,pc[210];
 4int C[210],dist[210][210][210]; 
 5bool mycmp(int a, int b){
 6    return (C[a]<C[b]);
 7}

 8int main(){
 9    int i,j,k,p,a,b,c;
10    scanf("%d",&T);
11    while(T--){
12        memset(dist,0xff,sizeof(dist));
13        scanf("%d%d",&N,&M);
14        C[pc[0]=0]=-1;
15        for(i=1;i<=N;i++){
16            scanf("%d",&C[i]);
17            pc[i]=i;
18        }

19        sort(pc,pc+N+1,mycmp);
20        for(i=1; i<=M; i++){
21            scanf("%d%d%d",&a,&b,&c);
22            dist[0][a+1][b+1]=c;
23            dist[0][b+1][a+1]=c;
24        }

25        //floyd
26        for(k=1; k<=N; k++){
27            p=pc[k];
28            for(i=1; i<=N; i++){
29                for(j=1; j<=N; j++){
30                    if(dist[k][i][j]<0)
31                        dist[k][i][j]=dist[k-1][i][j];
32                    else if(dist[k-1][i][j]>=0)
33                        dist[k][i][j]=min(dist[k][i][j],dist[k-1][i][j]);
34                        
35                    if(i!=&& dist[k-1][i][p]>=0 && dist[k-1][p][j]>=0){
36                        if(dist[k][i][j]<0)
37                            dist[k][i][j]=dist[k-1][i][p]+dist[k-1][p][j];
38                        else
39                            dist[k][i][j]=min(dist[k][i][j], dist[k-1][i][p]+dist[k-1][p][j]);
40                    }

41                    //printf("%d,%d,%d(%d) ",k,i,j,dist[k][i][j]);
42                }

43            }
        
44        }

45        //query
46        scanf("%d",&Q);
47        while(Q--){
48            scanf("%d%d%d",&a,&b,&c);
49            //顺序查找
50            for(i=0; i<=&& C[pc[i]]<=c; i++);
51            printf("%d\n",dist[i-1][a+1][b+1]);
52        }

53        printf("\n");
54    }

55    return 0;
56}

57
posted on 2009-03-31 14:39 wolf5x 阅读(226) 评论(0)  编辑 收藏 引用 所属分类: acm_icpcalgorithm

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

"Do not spend all your time on training or studying - this way you will probably become very exhausted and unwilling to compete more. Whatever you do - have fun. Once you find programming is no fun anymore – drop it. Play soccer, find a girlfriend, study something not related to programming, just live a life - programming contests are only programming contests, and nothing more. Don't let them become your life - for your life is much more interesting and colorful." -- Petr

留言簿(3)

随笔分类(59)

随笔档案(43)

cows

搜索

  •  

最新评论

评论排行榜