码迷,mamicode.com
首页 > Web开发 > 详细

(原创)网络(network)

时间:2017-07-28 22:24:05      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:cout   适配   logs   blog   bfs   ++   add   net   信息   

题目背景

Tsc是某国际学校信竞组的一只菜鸡。学校为了使教育信息化,打算在学校内新建机房,并且为机房联网。但吝啬的学校又不想花费过多的开销,于是将规划网络路线的任务交给了信竞组的Tsc。由于他是一只名副其实的菜鸡,他并不知道怎么规划,甚至不知道怎么打开编程软件,于是他又把这个任务交给了你。

题目描述

学校打算新建N(1<=N<=5)个机房,编号为1,2,…,N,这些机房错落在学校各个角落。为了联网,学校可以直接在机房内安装适配器,安装需要一定费用且每个机房费用不同。当然也可以借助其他的一些教室,从已安装适配器的地方接网线。这些教室不一定是机房,有M(1<=M<=1000)个非机房的教室,编号为N+1,N+2,…,N+M。这些教室也可以安装适配器,从而接网线到附近的机房。现给出每处安装适配器的费用以及教室间接网线的费用。求使所有机房连上网的费用最小值(非机房的教室没必要全联网)。

输入输出格式

输入格式:

第1行:三个整数N,M,Q(Q的含义下面有解释)

第2行:共N+M个整数,第i个数表示在编号为i的地方安装适配器费用Ai

第3~Q+2行:每行三个整数U,V,C,表示编号为U,V间连接网线的费用为C

输出格式:

共1行,1个整数,表示使所有机房连上网的费用最小值。

输入输出样例

输入样例#1:
3 1 3
1 2 3 4
1 4 2
2 4 2
3 4 4 
输出样例#1:
6
输入样例#2:
4 1 4
5 5 5 5 1
1 5 1
2 5 1
3 5 1
4 5 1 
输出样例#2:
5

说明

样例解释:

对于样例1:直接在每个机房安装适配器,开销最小,为1+2+3=6。

对于样例2:在唯一一个非机房的教室安装适配器,并从此处接网线到各个机房,开销最小,为1+1+1+1+1=5。

数据规模:

20%的数据有N=1;

另20%的数据有N=2;

另20%的数据有N=3;

100%的数据有1<=N<=5,1<=M<=1000,M<=Q<=5000,1<=A,C<=10000。

斯坦纳树的应用:

与模板相比,多了点权的设定,即一个联通块要有一个点权

方法很简单,设一个0节点,i点权值为x则加边(0,i,x),求部分点最小生成树(斯坦纳树)

斯坦纳树的概念和实现方法:http://blog.csdn.net/gzh1992n/article/details/9119543

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 struct Node
 7 {
 8     int next,to,dis;
 9 }edge[200001];
10 int q[100001],num,head[100001],dist[2001][2001],n,m,qq,f[(1<<7)][2001];
11 bool vis[100001];
12 void add(int u,int v,int dis)
13 {
14     num++;
15     edge[num].next=head[u];
16     head[u]=num;
17     edge[num].to=v;
18     edge[num].dis=dis;
19 }
20 void bfs(int x)
21 {int h,t,i;
22     q[1]=x;
23     h=0;t=1;
24     dist[x][x]=0;
25     memset(vis,0,sizeof(vis));
26     while (h<t)
27     {
28         h++;
29         int u=q[h];
30         vis[u]=0;
31          for (i=head[u];i;i=edge[i].next)
32          {
33              int v=edge[i].to;
34              if (dist[x][v]>dist[x][u]+edge[i].dis)
35              {
36                  dist[x][v]=dist[x][u]+edge[i].dis;
37                  if (vis[v]==0)
38                  {
39                      t++;
40                      q[t]=v;
41                      vis[v]=1;
42                  }
43              }
44          }
45     }
46 }
47 int main()
48 {int i,j,x,u,v,c,l;
49     cin>>n>>m>>qq;
50     memset(dist,127/3,sizeof(dist));
51     for (i=1;i<=n+m;i++)
52     {
53         scanf("%d",&x);
54         add(0,i,x);add(i,0,x);
55     }
56      for (i=1;i<=qq;i++)
57      {
58          scanf("%d%d%d",&u,&v,&c);
59          add(u,v,c);add(v,u,c);
60      }
61      for (i=0;i<=n+m;i++)
62      bfs(i);
63      memset(f,127/3,sizeof(f));
64      for (i=0;i<=n;i++)
65      {
66           for (j=0;j<=n+m;j++)
67           {
68               f[1<<i][j]=dist[i][j];
69           }
70      }
71      for (i=0;i<=n+m;i++)
72      {
73          f[0][i]=0;
74      }
75      for (int sta=1;sta<(1<<(n+1));sta++) if (sta&(sta-1))
76     {
77         for (int i=0;i<=n+m;i++)
78             for (int sub=sta;sub;sub=(sub-1)&sta)
79                 if (f[sta][i]>f[sub][i]+f[sta^sub][i])
80                     f[sta][i]=f[sub][i]+f[sta^sub][i];
81         for (int i=0;i<=n+m;i++)
82             for (int j=0;j<=n+m;j++)
83                 if (f[sta][i]>f[sta][j]+dist[j][i])
84                     f[sta][i]=f[sta][j]+dist[j][i];
85     }
86     cout<<f[(1<<n+1)-1][0];
87 }

 

(原创)网络(network)

标签:cout   适配   logs   blog   bfs   ++   add   net   信息   

原文地址:http://www.cnblogs.com/Y-E-T-I/p/7252521.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!