洛谷P3264 [JLOI2015]管道连接(斯坦纳树)

传送门

感觉对斯坦纳树还是有很多疑惑啊……

等到时候noip没有爆零的话再回来填坑好了

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<queue>
 5 #include<cstring>
 6 using namespace std;
 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 8 char buf[1<<21],*p1=buf,*p2=buf;
 9 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
10 inline int read(){
11     #define num ch-'0'
12     char ch;bool flag=0;int res;
13     while(!isdigit(ch=getc()))
14     (ch=='-')&&(flag=true);
15     for(res=num;isdigit(ch=getc());res=res*10+num);
16     (flag)&&(res=-res);
17     #undef num
18     return res;
19 }
20 const int N=1e6+5;
21 int head[N],Next[N],ver[N],edge[N],tot;
22 inline void add(int u,int v,int e){
23     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
24 }
25 int col[N],id[N],f[1105][1105],g[1105];
26 int vis[N],sum[N],n,m,k;
27 queue<int> q;
28 void spfa(int now){
29     while(!q.empty()){
30         int u=q.front();q.pop(),vis[u]=0;
31         for(int i=head[u];i;i=Next[i]){
32             int v=ver[i];
33             if(f[v][now]>f[u][now]+edge[i]){
34                 f[v][now]=f[u][now]+edge[i];
35                 if(!vis[v]) vis[v]=1,q.push(v);
36             }
37         }
38     }
39 }
40 int tmp[11];
41 bool check(int S){
42     memset(tmp,0,sizeof(tmp));
43     for(int i=1;i<=10;++i)
44     if(S&(1<<i-1)) ++tmp[col[i]];
45     for(int i=1;i<=10;++i)
46     if(tmp[i]&&tmp[i]!=sum[i]) return 0;
47     return 1;
48 }
49 int main(){
50 //    freopen("testdata.in","r",stdin);
51     n=read(),m=read(),k=read();
52     for(int i=1;i<=m;++i){
53         int u=read(),v=read(),e=read();
54         add(u,v,e),add(v,u,e);
55     }
56     memset(f,0x3f,sizeof(f));
57     memset(g,0x3f,sizeof(g));
58     for(int i=1;i<=k;++i)
59     col[i]=read(),id[i]=read(),++sum[col[i]],f[id[i]][1<<i-1]=0;
60     int limit=(1<<k)-1;
61     for(int S=0;S<=limit;++S){
62         for(int i=1;i<=n;++i){
63             for(int SS=S;SS;SS=(SS-1)&S)
64             cmin(f[i][S],f[i][SS]+f[i][S^SS]);
65             q.push(i),vis[i]=1;
66         }
67         spfa(S);
68     }
69     for(int S=0;S<=limit;++S)
70     for(int i=1;i<=n;++i)
71     cmin(g[S],f[i][S]);
72     for(int S=0;S<=limit;++S)
73     if(check(S))
74     for(int SS=S;SS;SS=(SS-1)&S)
75     if(check(SS))
76     cmin(g[S],g[SS]+g[S^SS]);
77     printf("%d\n",g[limit]);
78     return 0;
79 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9665249.html