-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhdu_3311_Dig The Wells.cpp
117 lines (105 loc) · 2.85 KB
/
hdu_3311_Dig The Wells.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
#define nMax 1010
#define mMax 13000
#define STA 1<<6
int n,s,tot,m;
int dp1[STA],dp[nMax][STA],first[nMax],next[mMax],st[nMax];
bool in[nMax][STA];
void init()
{
int i,j;
tot=0; s=(1<<(n+1));
for(i=0;i<=n+m;i++) first[i]=-1;
for(i=0;i<s;i++)
for(j=0;j<=n+m;j++)
dp[j][i]=-1,in[j][i]=false;
for(i=n+1;i<=m;i++) st[i]=0;
for(i=0;i<=n;i++) st[i]=(1<<i);
for(i=0;i<=n;i++) dp[i][st[i]]=0;
}
struct Edge{
int v,w;
}E[mMax];
inline void insert(int u,int v,int w){ E[tot].v=v; E[tot].w=w; next[tot]=first[u]; first[u]=tot++; }
queue<int>Q;
void SPFA()
{
int i,tmp,u,v,st1,st2,w;
while(!Q.empty()){
tmp=Q.front(); Q.pop();
u = tmp%nMax; st1 = tmp/nMax; in[u][st1]=false;
for(i=first[u];i!=-1;i=next[i]){
v=E[i].v; w=E[i].w; st2=(st1|st[v]);
if(dp[v][st2]==-1 || dp[v][st2]>dp[u][st1]+w){
dp[v][st2] = dp[u][st1] + w;
if(st1==st2 && !in[v][st2]) in[v][st2]=true,Q.push(st2*nMax+v);
}
}
}
}
void Steiner_Tree()
{
int i,j,t;
while(!Q.empty()) Q.pop();
for(i=0;i<s;i++){
for(j=0;j<=n+m;j++){
if(st[j] && !(st[j]&i)) continue;
for(t=(i-1)&i; t; t=(t-1)&i){
if(dp[j][t|st[j]]==-1 || dp[j][(i-t)|st[j]]==-1) continue;
if(dp[j][i]==-1 || dp[j][i]>dp[j][t|st[j]]+dp[j][(i-t)|st[j]])
dp[j][i] = dp[j][t|st[j]] + dp[j][(i-t)|st[j]];
}
if(dp[j][i]!=-1) in[j][i]=true,Q.push(i*nMax+j);
//printf("dp[%d][%d]=%d\n",j,i,dp[j][i]);
}
SPFA();
}
}
void DP()
{
int i,j,t;
for(i=0;i<s;i++){
dp1[i]=-1;
for(j=0;j<=n+m;j++){
if(st[j] && !(st[j] & i)) continue;
if(dp[j][i]==-1) continue;
if(dp1[i]==-1 || dp1[i]>dp[j][i]) dp1[i] = dp[j][i];
}
//printf("dp1[%d]=%d\n",i,dp1[i]);
}
for(i=0;i<s;i++) if( i&1 ){
for(j=0;j<=n+m;j++){
if( st[j] && !(i&st[j]) ) continue;
for( t=(i-1)&i; t; t=(t-1)&i ){
if(dp1[t|1]==-1 || dp1[(i-t)|1]==-1) continue;
if(dp1[i]==-1 || dp1[i]>dp1[i|1]+dp1[(i-t)|1]) dp1[i] = dp1[t|1]+dp1[(i-t)|1];
}
}
}
printf("%d\n",dp1[s-1]);
}
int main()
{
int p,u,v,w,i;
while(scanf("%d%d%d",&n,&m,&p)!=EOF){
init();
for(i=1;i<=n+m;i++){
scanf("%d",&w);
insert(0,i,w);
insert(i,0,w);
}
while(p--){
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
insert(v,u,w);
}
Steiner_Tree();
DP();
}
return 0;
}