[Luogu3264]

原题解

多个频道,每个频道的关键点要求相互联通

详见代码,非常巧妙

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} const int MAXN=1005;
const int MAXM=6005;
const int MAXL=1<<10; struct Edge{
int v,w,c,next;
}e[MAXM];
int first[MAXN],Ecnt=1;
inline void Add_edge(int u,int v,int w=0,int c=0){
e[++Ecnt]=(Edge){v,w,c,first[u]};
first[u]=Ecnt;
} struct Point{
int col,id;
inline friend bool operator < (Point a,Point b){
return a.col<b.col;
}
}a[12]; int f[MAXN][MAXL],g[MAXL];
bool inq[MAXN];
int n,m,K,Cnt;
queue <int> q; inline void SPFA(int sta){
while(!q.empty()){
int u=q.front();q.pop();inq[u]=false;
for(int i=first[u];i;i=e[i].next){
int v=e[i].v,w=e[i].w;
if(f[u][sta]+w<f[v][sta]){
f[v][sta]=f[u][sta]+w;
if(!inq[v]) inq[v]=true,q.push(v);
}
}
}
} inline int solve(int cnt){//一共只要考虑cnt个点
for(int i=1;i<(1<<cnt);i++){//这一维为基础:状态
for(int j=1;j<=n;j++){
for(int k=(i-1)&i;k;k=(k-1)&i)
f[j][i]=min(f[j][i],f[j][k]+f[j][i^k]);//再枚举j:以j为根连接状态了j的点
if(f[j][i]<f[0][0])
inq[j]=1,q.push(j);
}
SPFA(i);//我理解为暴力散开
}
int res=INF;
for(int i=1;i<=n;i++) res=min(res,f[i][(1<<cnt)-1]);
return res;
} int main(){
n=read(),m=read(),K=read();
for(int i=1;i<=m;i++){
int x=read(),y=read(),w=read();
Add_edge(x,y,w);
Add_edge(y,x,w);
}
for(int i=1;i<=K;i++)
a[i].col=read(),a[i].id=read();
sort(a+1,a+K+1);
for(int i=1;i<=K;i++){
if(a[i].col!=a[i-1].col) Cnt++;
a[i].col=Cnt;//离散化
}
Cnt=1<<Cnt;
memset(g,0x3f,sizeof g);
for(int i=1;i<Cnt;i++){
memset(f,0x3f,sizeof f);
int tmp=0;
for(int j=1;j<=K;j++){
if((1<<(a[j].col-1))&i)
f[a[j].id][1<<tmp++]=0;//i这些频道共有tmp个点
}
g[i]=solve(tmp);//i这些频道 <- 考虑这tmp个点的答案
}
for(int i=1;i<Cnt;i++){
for(int j=(i-1)&i;j;j=(j-1)&i)
g[i]=min(g[i],g[j]+g[i^j]);//再更新一次
}
printf("%d\n",g[Cnt-1]);
}

最新文章

  1. 【LeetCode】389 Find the Difference(java)
  2. centos 6.X 安装scrapy-原创
  3. mysql 清除数据库数据
  4. Apple 如何知道你使用了私有API
  5. 关于Redis的常识(推荐)
  6. 深入理解ajax系列第九篇——jQuery中的ajax
  7. dubbo在企业中用得多吗?
  8. [记录]MySQL读写分离(Atlas和MySQL-proxy)
  9. mybatis学习成长之路(一)
  10. FineReport性能调优的一些办法
  11. qml demo分析(maskedmousearea-异形窗口)
  12. linux下安装nodejs及npm
  13. springboot整合微软的ad域,采用ldap的api来整合,实现用户登录验证、
  14. python基础学习记录一
  15. Leetcode刷题第003天
  16. 排错-安装SQl&#160;2008“为SQL&#160;Server代理服务提供的凭据无效的解决方法
  17. C#控制台中创建数据库连接
  18. Java - 28 Java 泛型
  19. macaca自动化测试以及配置环境问题
  20. 【Mybatis】XML配置实现增删改查

热门文章

  1. javascript-文档结构遍历
  2. 50. Pow(x, n) 幂次方
  3. 69. Sqrt(x) 求根号再取整
  4. Django JSON-RPC
  5. UIView的alpha、hidden和opaque属性之间的关系和区别[转]
  6. Eclipse下Android的NDK开发环境配置
  7. Vue watch用法
  8. mysql 复制(主从复制)
  9. shipyard
  10. ### 20165219 2017-2018-2《Java程序设计》结对编程一 第二周总结