zoukankan      html  css  js  c++  java
  • Noip模拟 Day6.13 By LD T1

    一、哲哲回家

    出题人的解答:

    可以将其转化成最短路模型。

    这个地方转车怎么转移有点困难,有两种方法:

     1.我们可以再把每一个点拆成M个点,我们用F[i,j]表示从1号点到i这个点并且坐在j路车上的最少费用,对于同一条线路的相邻两个点,我们连一条权值为Rj的边,对于不在同一条     线路的两个点,连一条Rj+Tk的边,最后的答案就是min{f[n,i]}(1≤i≤m);

     2.我们定义f[i]为在点i处下车的最少费用,那么对于同一条路线上的点两两连边,费用为:经过的边数*Rj+Tk;可以发现Pi较小,使用后一种连边方式较优,点数是N,边数是M*P2。具体使用SPFA实现。

     

    连边比较麻烦,我写Dijkstra+Heap

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    typedef long long LL;
    
    #define INF 1<<30
    #define N 100010
    
    struct edge
    {
    	int v,w,next;
    }e[N];
    int head[N];
    int cnt;
    
    struct data
    {
    	int to,len;
    }p;
    
    struct cmp
    {
    	bool operator()(const data a,const data b)
    	{
    		return a.len>b.len;
    	}
    };
    
    int n,m,dian;
    int t,r,pp;
    int turn;
    
    int vis[N],dist[N];
    
    void link(int u,int v,int w)
    {
    	e[++cnt]=(edge){v,w,head[u]};
    	head[u]=cnt;
    }
    
    void Dij(int s)
    {
    	priority_queue<data,vector<data>,cmp>q;
    	for (int i=1;i<=dian;i++)
    		dist[i]=INF;
    	dist[s]=0;
    	vis[s]=1;
    	for (int i=head[s];i;i=e[i].next)
    		if (dist[e[i].v]>dist[s]+e[i].w)
    		{
    			dist[e[i].v]=dist[s]+e[i].w;
    			p.to=e[i].v;
    			p.len=dist[p.to];
    			q.push(p);
    		}
    	for (int i=1;i<=dian-1;i++)
    	{
    		if (q.empty())
    			break;
    		p=q.top();
    		q.pop();
    		while (vis[p.to] && !q.empty())
    			p=q.top(),q.pop();
    		int x=p.to;
    		//	int len=p.len;
    		vis[x]=1;
    		for (int j=head[x];j;j=e[j].next)
    			if (dist[e[j].v]>dist[x]+e[j].w)
    			{
    				dist[e[j].v]=dist[x]+e[j].w;
    				p.to=e[j].v;
    				p.len=dist[p.to];
    				q.push(p);
    			}		
    	}
    }
    
    int main()
    {
    	freopen("home.in","r",stdin);freopen("home.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	dian=n+1;
    	for (int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d",&t,&r,&pp);
    		for (int j=1;j<pp;j++)
    		{
    			scanf("%d",&turn);
    			link(turn,dian,t);
    			link(dian,turn,0);
    			link(dian,dian+1,r);
    			dian++;
    		}
    		link(dian,dian+1-pp,r);
    		scanf("%d",&turn);
    		link(turn,dian,t);
    		link(dian,turn,0);
    		dian++;
    	}
    	Dij(1);
    	printf("%d
    ",dist[n]);
    	return 0;
    }
    

      

    机房另外一个神犇写了spfa

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #ifdef WIN32   
    #define OT "%I64d"
    #else
    #define OT "%lld"
    #endif
    using namespace std;
    typedef long long LL;
    const int MAXN = 520;
    const int inf = (1<<30);
    int n,m;
    int dis[MAXN][MAXN];
    int next[MAXN][MAXN];
    int T[MAXN],R[MAXN],p[MAXN][MAXN];
    bool pd[MAXN][MAXN];
    
    struct node{
        int x,y;
    };
    
    queue<node>Q;
    int ans;
    
    inline int getint()
    {
    	int w=0,q=0;
    	char c=getchar();
    	while((c<'0' || c>'9') && c!='-') c=getchar();
    	if (c=='-')  q=1, c=getchar();
    	while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    	return q ? -w : w;
    }
    
    inline void spfa(){
        for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			dis[i][j]=inf;
    
        while(!Q.empty()) Q.pop();
    
        node lin;
        for(int i=1;i<=n;i++)
    		if(next[i][1]!=0){
    			lin.x=i; lin.y=1;
    			Q.push(lin);
    			dis[i][1]=T[i];
    			pd[i][1]=1;
    		}
    
        while(!Q.empty()) {
    		int x=Q.front().x; int y=Q.front().y; Q.pop(); 
    		pd[x][y]=0;
            for(int i=1;i<=n;i++) {
    			if(i!=x) {
    				if(next[i][y]==0) continue;
    				if(dis[i][y]>dis[x][y]+T[i]) {
    					dis[i][y]=dis[x][y]+T[i];
    					if(!pd[i][y]) {
    						pd[i][y]=1;
    						lin.x=i; lin.y=y;
    						Q.push(lin);
    					} 
    				} 
    			} else{
    				if(dis[x][next[x][y]]>dis[x][y]+R[i]) {
    					dis[x][next[x][y]]=dis[x][y]+R[i];
    					if(!pd[x][next[x][y]]) {
    						pd[x][next[x][y]]=1;
    						lin.x=x; lin.y=next[x][y];
    						Q.push(lin);
    					} 
    				}
    			}
    		}
        }
    
        ans=inf;
        for(int i=1;i<=n;i++) {
    		if(dis[i][n]<ans) ans=dis[i][n];
        }
    }
    
    inline void solve(){
        n=getint(); m=getint();
        for(int i=1;i<=m;i++) {
    		T[i]=getint(); R[i]=getint(); p[i][0]=getint();
    		for(int j=1;j<=p[i][0];j++) {
    			p[i][j]=getint(); if(j!=1) next[i][p[i][j-1]]=p[i][j];
    		}
    		if(p[i][0]>0) next[i][p[i][p[i][0]]]=p[i][1];
        }
    
        spfa();
    
        printf("%d",ans);
    }
    
    int main()
    {
    	freopen("home.in","r",stdin);
    	freopen("home.out","w",stdout);
    	solve();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

      

  • 相关阅读:
    谈谈 OC 中的内联函数
    Spring 新手教程(二) 生命周期和作用域
    实时竞价(RTB) 介绍(基础篇)
    oracle数据库性能优化方案精髓整理收集回想
    HNU 13411 Reverse a Road II(最大流+BFS)经典
    CSS3主要知识点复习总结+HTML5新增标签
    修改默认MYSQL数据库data存放位置
    mysql状态查看 QPS/TPS/缓存命中率查看
    Mysql5.7.10新加用户
    很靠谱linux常用命令
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5585687.html
Copyright © 2011-2022 走看看