[Cattle off] twelve bridge problem
The meaning of problems
There is a \ (n-\) points \ (m \) with the right edges of the directed graph \ ((n-\ Le 50000, \ m \ Le 200000) \) ,
which \ (K \) edges is constant to go through \ ((k \ Le 12) \) ,
From node \ (1 \) starting requirements: after all must go through the side, back to the node \ (1 \) is the shortest path.
Thinking
First, although the relatively large number of points, but most of it is useless, we only need to focus on a few sides that must endpoint (or bridge) is.
Therefore, the beginning of the first respectively \ (1 \) nodes and endpoints all the bridges as a starting point, running several times \ (Dijkstra \) , and the shortest distance between the number of points to build a new map.
Then, consider the shape pressure DP, provided \ (f [u] [i ] \) of the current point \ (U \) , after a set of edges (bridge set) of \ (I \) shortest path when.
But since this is an undirected graph, there is no topological order, can not be directly dp,
so every time we enumerate a set of edges, the first update all selected endpoints to the bridge \ (f \) values, and the these points added to the priority queue, and then running side dijkstra, the rest of all the points have been updated.
Code
#include<bits/stdc++.h>
#define ll long long
#define mkp make_pair
using namespace std;
const int N=5e4+7;
const int M=2e5+7;
const int K=12+7;
const int L=4096+7;
int n,m,k,all,poi,num[N],cnt,bdg[2*K][2*K],bi[K],rec[L];
ll f[2*K+1][L],dis[N],mp[2*K+1][2*K+1],ans,inf;
int lst[N],nxt[2*M],to[2*M],tot;
ll len[2*M];
bool b[N];
struct bridge{
int x,y;
ll w;
}e[M];
void add(int x,int y,ll w){
nxt[++tot]=lst[x];
to[tot]=y;
len[tot]=w;
lst[x]=tot;
}
void read(){
cin>>n>>m>>k; num[1]=++cnt; int x,y;
for(int i=1;i<=m;i++){
scanf("%d%d%lld",&x,&y,&e[i].w);
if(!num[x]) num[x]=++cnt;
if(!num[y]) num[y]=++cnt;
x=num[x];
y=num[y];
e[i].x=x;
e[i].y=y;
add(x,y,e[i].w);
add(y,x,e[i].w);
if(i<=k){ bdg[x][y]=bdg[y][x]=i; poi=cnt; }
}
for(int i=1;i<=k;i++){ bi[i]=1<<i-1; rec[bi[i]]=i; }
all=(1<<k)-1;
memset(f,127,sizeof(f));
memset(mp,-1,sizeof(mp));
inf=f[0][0];
}
priority_queue<pair<ll,int> >h;
void dijk(int st){
memset(dis,127,sizeof(dis));
memset(b,0,sizeof(b));
dis[st]=0;
h.push(mkp(0,st));
while(!h.empty()){
int u=h.top().second; h.pop();
if(b[u]) continue;
b[u]=1;
for(int i=lst[u];i;i=nxt[i])
if(dis[to[i]]>dis[u]+len[i]){
dis[to[i]]=dis[u]+len[i];
h.push(mkp(-dis[to[i]],to[i]));
}
}
for(int i=1;i<=2*k+1;i++)
if(dis[i]!=inf) mp[st][i]=dis[i];
}
void print(int x){
for(int i=1;i<=k;i++){
printf("%d",x&1);
x>>=1;
}
}
void run(int i){
while(!h.empty()){
int u=h.top().second; h.pop();
if(b[u]) continue;
b[u]=1;
for(int v=1;v<=n;v++)
if(mp[u][v]!=-1&&f[v][i]>f[u][i]+mp[u][v]){
f[v][i]=f[u][i]+mp[u][v];
h.push(mkp(-f[v][i],v));
}
}
}
int main(){
// freopen("bridge.in","r",stdin);
// freopen("bridge.out","w",stdout);
read();
for(int i=1;i<=2*k+1;i++) dijk(i);
f[1][0]=0; h.push(mkp(0,1));
n=poi;
ans=inf;
for(int i=0;i<=all;i++){
for(int j=i;j;j-=j&-j){
int t=rec[j&-j];
int x=e[t].x,y=e[t].y;
f[x][i]=min(f[x][i],f[y][i^bi[t]]+e[t].w);
f[y][i]=min(f[y][i],f[x][i^bi[t]]+e[t].w);
h.push(mkp(-f[x][i],x));
h.push(mkp(-f[y][i],y));
}
memset(b,0,sizeof(b));
run(i);
}
for(int i=1;i<=n;i++)
if(f[i][all]!=inf) ans=min(ans,f[i][all]+mp[i][1]);
printf("%lld\n",ans);
return 0;
}