• PAT 1087【二级最短路】


    尴尬二级最短路+二级最短路,就是DP过程吧。
    代码稍微注释一些,毕竟贴代码不好。。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int INF=0x3f3f3f3f;
    const int N=4e4+10;
    struct asd{
    	int cost;
    	int to;
    	int next;
    }e[N];
    int head[220],tol,tot;
    int n,m,w[220];
    map<string,int>mp;
    map<int,string>ip;
    
    int GetID(string s)
    {
    	if(mp.find(s)!=mp.end()) return mp[s];
    	return mp[s]=++tot;
    }
    void init()
    {
    	tol=tot=0;
    	memset(head,-1,sizeof(head)); 
    }
    void add(int u,int v,int cost)
    {
    	e[tol].cost=cost;
    	e[tol].to=v;
    	e[tol].next=head[u];
    	head[u]=tol++;
    }
    
    queue<int>q;
    vector<int>xs;
    bool vis[220];
    int pre[N];		//记录路径 
    int dis[220];	//距离花费 
    int hap[220];	//到位置 v 的最大开心值 
    int all[220];	//到位置 v 的所有开心值总和 
    int rotu[220];	//到位置 v 的路线条数 
    int num[220];	//到位置 v 的结点个数 
    int ave[220];	//到位置 v 的最大平均数 
    void SPFA(int s,int t)		//利用SPFA算法(最短路比较喜欢的算法,有可能会卡常数。 
    {
    	xs.clear();
    	while(!q.empty()) q.pop();
    	for(int i=1;i<=n;i++)
    	{
    		vis[i]=false;
    		dis[i]=INF;
    		num[i]=rotu[i]=all[i]=hap[i]=0;
    	}
    	pre[s]=-1;
    	rotu[s]=1;
    	vis[s]=true;
    	dis[s]=0;
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();q.pop();
    		vis[u]=false;
    		for(int i=head[u];~i;i=e[i].next)
    		{
    			int v=e[i].to;
    			if(dis[v]>dis[u]+e[i].cost)		//一旦这个花费大了,所有都要更新 
    			{
    				pre[v]=u;
    				dis[v]=dis[u]+e[i].cost;
    				all[v]=hap[v]=hap[u]+w[v];
    				rotu[v]=rotu[u];
    				num[v]=num[u]+1;
    				ave[v]=all[v]/num[v];
    				if(!vis[v])
    				{
    					vis[v]=true;
    					q.push(v);
    				}
    			}
    			else if(dis[v]==dis[u]+e[i].cost)	//花费相同,更新路径 
    			{
    				rotu[v]+=rotu[u];
    				if(hap[v]<hap[u]+w[v])			//开心值取大的 
    				{
    					pre[v]=u;
    					all[v]=hap[v]=hap[u]+w[v];
    					num[v]=num[u]+1;
    					ave[v]=all[v]/num[v];
    				}
    				else if(hap[v]==hap[u]+w[v])	//开心值相同,判断最大平均数 
    				{
    					int t_all,t_ave,t_num;
    					t_all=hap[u]+w[v];
    					t_num=num[u]+1;
    					t_ave=t_all/t_num;
    					ave[v]=max(ave[v],t_ave);
    				}
    			}
    		}
    	}
    	int x=t;
    	while(x!=-1)
    	{
    		xs.push_back(x);
    		x=pre[x];
    	}
    	printf("%d %d %d %d
    ",rotu[t],dis[t],hap[t],ave[t]);
    	int sz=xs.size();
    	for(int i=sz-1;i>=0;i--)
    	{
    		if(i!=sz-1) cout<<"->";
    		cout<<ip[xs[i]];
    	}
    }
    
    int main()
    {
    	string be,st;
    	int x,idx,idy,id,s,t;
    	cin>>n>>m>>be;
    	s=GetID(be);
    	ip[s]=be;
    	for(int i=1;i<n;i++)
    	{
    		cin>>be>>x;
    		id=GetID(be);ip[id]=be;
    		w[id]=x;
    	}
    	init();
    	while(m--)
    	{
    		cin>>be>>st>>x;
    		idx=GetID(be);
    		idy=GetID(st);
    		add(idx,idy,x);
    		add(idy,idx,x);
    	}
    	t=mp["ROM"];
    	SPFA(s,t);
    	return 0;
    }
    


  • 相关阅读:
    在 ASP.NET 2.0 中上载文件
    ASP.NET(C#)FileUpload实现上传限定类型和大小的文件到服务器<from Copying>
    aspnetupload 上传组件在VS2008中使用详细说明
    基于asp.net 的文件上传和下载~~~转
    设置竖直的分割符【使用div】 (根据屏幕的大小自适应)
    分隔线
    UGUI事件系统
    U3D音频系统
    Unity启动事件-监听:InitializeOnLoad
    VS生成桌面应用程序
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777373.html
Copyright © 2020-2023  润新知