zoukankan      html  css  js  c++  java
  • 【题解】P1119 灾后重建

    我感觉这道题的思路十分巧妙,巧妙地利用了 (Floyd) 的思想,来做出这道题,不得不说, (A) 掉了这题以后,我感觉自己对 (Floyd) 的实质了解了更多。

    思路

    事实上,我们都知道 (Floyd) 的标准代码长这样

    for(int k=1;k<=n;++k)  
      for(int i=1;i<=n;++i)  
        for(int j=1;j<=n;++j)  
          f[i][j]=min(f[i][j],f[i][k]+f[k][j]);  
    

    那么对于这道题,对于每一个村庄,我们都有一个时间 (time_i) ,只有每条路线相连的两个村庄修好的时间恰好小于等于当前询问的时间(注:询问的时间是保证单调递增的),这条路线才是有效的。
    对于每一个修好的村庄 (i) ,我们可以将所有连着 (i) 村庄的村庄的最短路更新一遍,代码实现为

    void update(int k)
    {
    	for(int i=0;i<n;++i)
    		for(int j=0;j<n;++j)
    			f[i][j]=f[j][i]=min(f[i][j],f[i][k]+f[k][j]);
    }
    

    没错,跟普通的 (Floyd) 是大致一样的,只不过是我们给出了单独更新的 (k)
    (Code:)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int tot,n,m;
    int t[211],f[211][211];
    bool book[211];
    void update(int k)
    {
    	for(int i=0;i<n;++i)
    		for(int j=0;j<n;++j)
    			f[i][j]=f[j][i]=min(f[i][j],f[i][k]+f[k][j]);
    }
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	int inf=1e9;
    	scanf("%d %d",&n,&m);
    	for(int i=0;i<n;++i) scanf("%d",&t[i]);
    	for(int i=0;i<n;++i)
    		for(int j=0;j<n;++j)	
    			f[i][j]=inf;
    	for(int i=1;i<=m;++i)
    	{
    		int u,v,w;
    		scanf("%d %d %d",&u,&v,&w);
    		f[u][v]=f[v][u]=w;
    	}
    	int Q,now=0;
    	scanf("%d",&Q);
    	for(int i=1;i<=Q;++i)
    	{
    		int x,y,ta;
    		scanf("%d %d %d",&x,&y,&ta);
    		while(t[now]<=ta && now<n)
    		{
    			book[now]=true; 
    			update(now);		
    			++now;
    		}
    		if(t[x]>ta || t[y]>ta || f[x][y]==inf) printf("-1
    ");
    		else printf("%d
    ",f[x][y]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    大于00
    today
    10
    面试题flask
    开发者日志
    7月22日一天学的东西
    资料
    3333
    2222
    1
  • 原文地址:https://www.cnblogs.com/Call-me-zhz/p/11316115.html
Copyright © 2011-2022 走看看