zoukankan      html  css  js  c++  java
  • Abandoning Roads CodeForces

    大意: 给定无向图, 边权只有两种, 对于每个点$x$, 输出所有最小生成树中, 点$1$到$x$的最短距离.

    先将边权为$a$的边合并, 考虑添加边权为$b$的边.

    每条路径只能经过每个连通块一次, 直接状压的话有$O(n2^n)$个状态.

    但是注意到点数不超过$3$的连通块内部最短路不超过$2a$, 所以求最短路时一定只经过$1$次, 所以可以不考虑.

    这样总状态就为$O(n2^{frac{n}{4}})$.

    #include <iostream>
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <bitset>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
    ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
    inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
    //head
    
    
    
    const int N = 1e7+10;
    int n, m, tot, a, b, fa[555], sz[555], id[555];
    struct _ {int to,w;};
    vector<_> g[555];
    int Find(int x) {return fa[x]?fa[x]=Find(fa[x]):x;}
    void add(int x, int y) {
    	x=Find(x),y=Find(y);
    	if (x!=y) fa[x]=y,sz[y]+=sz[x];
    }
    struct __ {
    	int id, w;
    	bool operator < (const __ &rhs) const {
    		return w>rhs.w;
    	}
    };
    priority_queue<__> q;
    int dis[N], cnt;
    int ID(int x, int y) {
    	return x*n+y;
    }
    pii get(int s) {
    	return pii((s-1)/n,(s-1)%n+1);
    }
    
    int main() {
    	scanf("%d%d%d%d", &n, &m, &a, &b);
    	REP(i,1,n) sz[i]=1;
    	REP(i,1,m) {
    		int u, v, c;
    		scanf("%d%d%d", &u, &v, &c);
    		g[u].pb({v,c}),g[v].pb({u,c});
    		if (c==a) add(u,v);
    	}
    	REP(i,1,n) if (i==Find(i)&&sz[i]>3) {
    		REP(j,1,n) if (Find(j)==i) id[j] = 1<<tot;
    		++tot;
    	}
    	int mx = (1<<tot)-1;
    	memset(dis,0x3f,sizeof dis);
    	q.push({ID(id[1],1),dis[ID(id[1],1)]=0});
    	while (q.size()) {
    		__ t = q.top(); q.pop();
    		int u = t.id, w = t.w;
    		if (dis[u]!=w) continue;
    		for (auto &e:g[get(u).y]) {
    			int v = ID(get(u).x|id[e.to],e.to);
    			if (e.w==a) {
    				if (dis[v]>w+a) q.push({v,dis[v]=w+a});
    			}
    			else if (Find(get(u).y)!=Find(e.to)&&!(get(u).x&id[e.to])) {
    				if (dis[v]>w+b) q.push({v,dis[v]=w+b});
    			}
    		}
    	}
    	REP(i,1,n) {
    		int ans = INF;
    		REP(j,0,mx) ans = min(ans, dis[ID(j,i)]);
    		printf("%d ", ans);
    	} hr;
    }
    
  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/uid001/p/11134444.html
Copyright © 2011-2022 走看看