標籤: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 31 2 3 41 4 22 4 23 4 4
輸出範例#1:
6
輸入範例#2:
4 1 45 5 5 5 11 5 12 5 13 5 14 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)