zoukankan      html  css  js  c++  java
  • poj 3662 Telephone Lines spfa算法灵活运用

    意甲冠军:

    到n节点无向图,它要求从一个线1至n路径。你可以让他们在k无条,的最大值。如今要求花费的最小值。

    思路:

    这道题能够首先想到二分枚举路径上的最大值,我认为用spfa更简洁一些。spfa的本质是一种搜索算法,既然是搜索,就涉及到状态的转移。

    在一般求最短路的spfa算法中,当到结点u时,对e(u,v)仅仅需做例如以下转移:if(d[v]>d[u]+w(e)) d[v]=d[u]+w(e)。在跟一般的情况下。到结点u,对e(u,v)需做多种转移。比方这题中要考虑让e免费和不让e免费两种情况,详细的请參考实现。

    代码:

    //poj 3662
    //sepNINE
    #include <iostream>
    #include <queue>
    using namespace std;
    const int maxN=1024;
    const int maxM=10024;
    
    struct Edge
    {
    	int v,w,next;
    }edge[maxM*2];
    
    struct Node
    {
    	int u,used;	
    };
    int n,p,k,e;
    int head[maxN],dis[maxN][maxN],vis[maxN][maxN];
    
    void spfa(int s,int t,int k)
    {
    	queue<Node> Q;
    	memset(vis,0,sizeof(vis));
    	int i,j;
    	for(i=1;i<=n;++i)
    		for(j=0;j<=k;++j)
    			dis[i][j]=INT_MAX;	
    	Node x;
    	x.u=s;
    	x.used=0;
    	dis[s][0]=0;
    	vis[s][0]=1;
    	Q.push(x);
    	while(!Q.empty()){
    		Node x=Q.front();
    		int u=x.u,used=x.used;
    		Q.pop();
    		vis[u][used]=0;	
    		for(int i=head[u];i!=-1;i=edge[i].next){
    			int v=edge[i].v,w=edge[i].w;
    			if(used+1<=k&&dis[v][used+1]>dis[u][used]){//让这条边免费,免费的边数used要+1
    				dis[v][used+1]=dis[u][used];
    				if(vis[v][used+1]==0){
    					Node x;
    					x.u=v;x.used=used+1;
    					vis[x.u][x.used]=1;
    					Q.push(x);					
    				}
    			} 
    			if(dis[v][used]>max(dis[u][used],w)){//不让这条边免费。dis[v][used]为dis[u][used]和w中的最大值
    				dis[v][used]=max(dis[u][used],w);
    				if(vis[v][used]==0){
    					Node x;
    					x.u=v;x.used=used;
    					vis[x.u][x.used]=1;
    					Q.push(x);
    				}
    			}
    		}
    		
    	}
    	return ;
    }
    
    int main()
    {
    	scanf("%d%d%d",&n,&p,&k);
    	e=0;
    	memset(head,-1,sizeof(head)); 
    	while(p--){
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		edge[e].v=b;edge[e].w=c,edge[e].next=head[a];head[a]=e++;
    		edge[e].v=a;edge[e].w=c;edge[e].next=head[b];head[b]=e++;
    	}
    	spfa(1,n,k);
    	int ans=INT_MAX;
    	for(int i=0;i<=k;++i)
    		ans=min(ans,dis[n][i]);
    	if(ans==INT_MAX)
    		printf("-1");
    	else
    		printf("%d",ans);	
    	return 0;	
    } 


  • 相关阅读:
    Vagrant安装virtualbox
    SQLSERVER排查CPU占用高的情况
    删除重复记录,只留一条
    ASCII码对应表chr(9)、chr(10)、chr(13)、chr(32)、chr(34)、chr(39)、……
    手机和PC端的录屏软件
    2017年初面试总结
    Python面向对象
    Python字体颜色
    Python第二模块总结
    Fiddler使用教程(转)
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4740387.html
Copyright © 2011-2022 走看看