zoukankan      html  css  js  c++  java
  • 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;
    }
    


  • 相关阅读:
    吃货联盟项目
    字串符笔记
    带有参的方法
    js:自动亮起100盏灯
    JS字面量创建方式的优缺点
    为什么说对象字面量赋值比new Object()高效?
    javascript 字面量
    vue学习(一)、Vue.js简介
    Redis(二):c#连接Redis
    Redis(一):centos下安装。
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777373.html
Copyright © 2011-2022 走看看