zoukankan      html  css  js  c++  java
  • Bzoj3040 dijkstra堆优化+链式前向星

    Bzoj3040 dijkstra堆优化+链式前向星

    问题描述:

    N个点,M条边的有向图,求点1到点N的最短路(保证存在)。
    1<=N<=1000000,1<=M<=10000000

    input:

    第一行两个整数N、M,表示点数和边数。
    第二行六个整数T、rxa、rxc、rya、ryc、rp。

    前T条边采用如下方式生成:
    1.初始化x=y=z=0。
    2.重复以下过程T次:
    x=(xrxa+rxc)%rp;
    y=(y
    rya+ryc)%rp;
    a=min(x%n+1,y%n+1);
    b=max(y%n+1,y%n+1);
    则有一条从a到b的,长度为1e8-100*a的有向边。

    后M-T条边采用读入方式:
    接下来M-T行每行三个整数x,y,z,表示一条从x到y长度为z的有向边。

    1<=x,y<=N,0<z,rxa,rxc,rya,ryc,rp<2^31

    output:

    一个整数,表示1~N的最短路。

    Sample input:

    3 3
    0 1 2 3 5 7
    1 2 1
    1 3 3
    2 3 1

    Sample output:

    2

    先介绍一下一种新的存图方式:链式前向星

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXV = ;//图中点的最大值
    const int MAXN = ;//图中边的最大值
    int head[MAXN];//head[u]就代表u为起点的第一条边在edge数组中的下标
    int cnt = 0;//cnt 代表当前的所有边的边数
    struct EDGE{
        int v;//这条边所指向的顶点
        int next;//下一条边在edge数组中的下标 默认是0
        int w;//边的权值
    };
    EDGE edge[MAXN];
    Add (int x,int y,int w) {//添加边的操作,x->y 权值为w
    	edge[++cnt].next = head[x];//逆序添加边,添加的边为head[x]所代表的 
    	edge[cnt].v = y;
        edge[cnt].w = w;
        head[x] = cnt;
    }
    void Print(int u) {//遍历操作,从u顶点开始遍历由该顶点出发的所有边 
    	for(int i = head[u];i != 0;i = edge[i].next) {
    	printf("%d %d
    ",edge[i].v,edge[i].w);
    	}
    }	
    

    这题如果不用链式前向星存的话会爆内存。。。 当然也有神仙通过配对堆优化来卡过内存 总之简单的使用dijkstra堆优化来写的话就会mle(还有牛逼老哥用斐波那契堆优化过的orz hhhhhh)

    当然仅仅用链式前向星的话也是没用的,你还会因为你的优先队列入队太多而re掉(呜呜呜呜这什么神仙题卡了我一整天,归根到底还是我太菜了hhhhhh(这题其实前面的T条边实在假你,因为前面的边对最短路根本没有贡献

    ac代码如下:

    
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6 + 5;
    const int maxm = 1e7 + 5;
    const int tt = 1e8;
    int n, m, dis[maxn];
    int t, rxa, rxc, rya, ryc, rp;
    struct edge{
    	int to, w, next;
    } ed[maxm];
    int head[maxn], tot;
    bool vis[maxn];
    inline void add( int u, int v, int w ){
    	ed[++tot].to = v;
    	ed[tot].w = w;
    	ed[tot].next = head[u];
    	head[u] = tot;
    }
    inline void dij(int beg){
    	priority_queue< pair<int, int> > q;
    	dis[beg] = 0;
    	q.push(make_pair(0, beg));
    	while( !q.empty() ){
    		int u = q.top().second;
    		q.pop();
    		if( vis[u] ) continue;
    		vis[u] = 1;
    		for( int i=head[u]; i!=0; i=ed[i].next ){
    			int v = ed[i].to;
    			if(vis[v]) continue;
    			if( dis[v]>dis[u]+ed[i].w ){
    				dis[v] = dis[u]+ed[i].w;
    				q.push( make_pair(-dis[v], v) );
    			}
    		}
    	}
    }
    
    int main(){
    	memset( vis, 0, sizeof(vis) );
    	memset( dis, 0x3f, sizeof(dis) );
    	tot = 1;
    	scanf("%d%d", &n, &m);
    	scanf("%d %d %d %d %d %d", &t, &rxa, &rxc, &rya, &ryc, &rp);
    	for( int i=0; i<t; i++ ){
    		int x, y, a, b, w;
    		x = (x*rxa+rxc)%rp;
    		y = (y*rya+ryc)%rp;
    		a = min(x%n+1, y%n+1);
    		b = max(y%n+1, y%n+1);
    		w = tt-100*a;
    		add( a, b, w );
    	}
    	for( int i=t; i<m; i++ ){
    		int u, v, w;
    		scanf("%d%d%d", &u, &v, &w);
    		add( u, v, w );
    	}
    	dij(1);
    	printf("%d
    ", dis[n]);
    
    	return 0;
    }
    
    我现在最大的问题就是人蠢而且还懒的一批。
  • 相关阅读:
    20200924-5 四则运算试题生成,结对
    20200924-4 代码规范,结对要求
    20200929-git地址
    20200917-1 每周例行报告
    20200917-3白名单
    20200917-2 词频统计
    20200910-1 每周例行报告
    20200910-2 博客作业
    20200924-3 单元测试,结对
    20200924-5 四则运算试题生成,结对
  • 原文地址:https://www.cnblogs.com/pot-a-to/p/10936821.html
Copyright © 2011-2022 走看看