大意: 给定无向图, 边权只有两种, 对于每个点$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 '\n'
#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;
}

Abandoning Roads CodeForces - 1149D (最小生成树)的更多相关文章

  1. Fools and Roads CodeForces - 191C

    Fools and Roads CodeForces - 191C 题意:给出一棵n个节点的树,还有树上的k条简单路径(用路径的两个端点u和v表示),对于树上每一条边,求出其被多少条简单路径经过. 方 ...

  2. @codeforces - 1149D@ Abandoning Roads

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n 点 m 条边的无向连通图,每条边的边权为 a 或 ...

  3. CF1149D Abandoning Roads(图论,最短路,状态压缩,最小生成树)

    题目大意:$n$ 个点,$m$ 条边的无向图,边权只有两种,小的为 $a$,大的为 $b$. 对于每个点 $p$,询问在这张图所有的最小生成树上,$1$ 到 $p$ 的最短距离的最小值. $2\le ...

  4. Codeforces Round #556 CF1149D Abandoning Roads

    这道题并不简单,要得出几个结论之后才可以做.首先就是根据Kruskal求最小生成树的过程,短边是首选的,那么对于这道题也是,我们先做一次直选短边的最小生成树这样会形成多个联通块,这些联通块内部由短边相 ...

  5. [Usaco2007 Dec]Building Roads 修建道路[最小生成树]

    Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农 ...

  6. HDU 1102(Constructing Roads)(最小生成树之prim算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Ja ...

  7. hdu 1301 Jungle Roads krusckal,最小生成树,并查集

    The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was s ...

  8. Constructing Roads(1102 最小生成树 prim)

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. codeForces 472D 最小生成树

    题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...

随机推荐

  1. C#图片灰度处理(位深度24→位深度8)、C#图片二值化处理(位深度8→位深度1)

    C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> / ...

  2. API的查看

    步骤: 1. 双击打开API 2. 点击显示, 找到索引 3. 输入要查找的类名 , 敲击Enter两次 4. 看该类所属的包, java.lang包下的类,在使用的时候不需要导包 ,其他的都需要导包 ...

  3. 算法习题---3.01猜数字游戏提示(UVa340)

    一.题目 实现一个经典“猜数字”游戏.给定答案序列和用户猜的序列,统计有多少数字位置正确(A),有多少数字在两个序列都出现过但位置不对(B). 输入包含多组数据.每组输入第一行为序列长度n,第二行是答 ...

  4. 【408】C函数中的ADT

    类似类的形式 boardADT.h:所有的宏.声明等部分写在这里 boardADT.c:只需要 #inclue "boardADT.h",不需要 include 其他系统头文件,然 ...

  5. (一)深入java虚拟机之内存溢出与分析

    一.内存溢出程序 public class Test { public static void main(String[] args) { List<User> userList=new ...

  6. php关于文件上传的两个配置项说明

    ; Maximum allowed size for uploaded files.; http://php.net/upload-max-filesizeupload_max_filesize = ...

  7. ADFS2016和ADFS代理的安装与配置

    一,ADFS安装教程 教程链接(包含安装和配置两个步骤): https://www.virtuallyboring.com/how-to-setup-microsoft-active-director ...

  8. iOS-DatePicket

    组件_DatePicket /** 1.初始化 2.设置选择控件的格式 3.设置日期选择控件的地区 4.监听日期选择控件数值变化 **/ UIDatePicker *datePicker = [[UI ...

  9. javascript正则总结

    目录 1. 正则基础知识 2. 正则实例 3. 正则常见问题 4. 开发常用validate 5. 网上整理的正则 1. 正则基础知识 精确匹配: /test/ 匹配一类字符:匹配a,b,c任一字符/ ...

  10. laravel-excel 表格 文档翻译笔记

    原文地址:https://blog.csdn.net/beyond__devil/article/details/78117471 1.安装 1>composer 安装 "maatwe ...