最省路径(异或优化建图)

时间:2021-04-19 15:01:49   收藏:0   阅读:0
此题我要讲一种异或优化建图

因此建边如下:

for(int i=1;i<=m;i++) {
    int u,v;ll w;
    scanf("%d%d%lld",&u,&v,&w);
    add_edge(u,v,w);
}
for(int i=0;i<=n;i++) {
    for(int j=0;j<=20;j++) {
	int v=i^(1<<j);
	if(v<=n) {
	   add_edge(i,v,(1<<j)*c);
	}
    }
}

所整体从起点A跑一遍Dijkstra就可以了
(图论的核心是如何建边)会了上面的建边代码很简单:

    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    const int M=1e7+5;
    int nxt[M],to[M],head[N],tot;
    ll len[M],dis[N];
    void add_edge(int u,int v,ll w) {
    	tot++; nxt[tot]=head[u]; len[tot]=w; to[tot]=v; head[u]=tot;
    }
    struct node {
    	int p;ll w;
    	bool operator<(const node &u) const{return w>u.w;}
    };
    priority_queue<node> Q;
    bool mark[N];
    void DJ(int s) {
    	Q.push((node){s,0});
    	dis[s]=0;
    	while(!Q.empty()) {
    		int u=Q.top().p; Q.pop();
    		if(mark[u]) continue;
    		mark[u]=true;
    		for(int i=head[u];i;i=nxt[i]) {
    			int v=to[i];
    			if(!mark[v]&&dis[v]>dis[u]+len[i]) {
    				dis[v]=dis[u]+len[i];
    				Q.push((node){v,dis[v]});
    			}
    		}
    	}
    }
    int main() {
    	int n,m,c,X,Y;
    	scanf("%d%d%d",&n,&m,&c);
    	for(int i=1;i<=m;i++) {
    		int u,v;ll w;
    		scanf("%d%d%lld",&u,&v,&w);
    		add_edge(u,v,w);
    	}
    	for(int i=0;i<=n;i++) {
    		for(int j=0;j<=20;j++) {
    			int v=i^(1<<j);
    			if(v<=n) {
    				add_edge(i,v,(1<<j)*c);
    //				printf("%d %d %lld\n",i,v,(1<<j)*c);
    			}
    		}
    	}
    	scanf("%d%d",&X,&Y);
    	memset(dis,0x3f,sizeof(dis));
    	DJ(X);
    	printf("%lld",dis[Y]);
    	return 0;
    }
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!