生活随笔
收集整理的這篇文章主要介紹了
hdu6832(2020hdu多校6t6)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題解
所有最短路肯定都出現在最小生成樹上。因為克魯斯卡爾按順序連邊,前面已經連上的肯定最優,所有加起來比當前的還小。
這個我感覺求單源多匯最短路后的剩余圖其實和最小生成樹其實是一樣的。因為如果最小生成樹的結論是對的,那么源點到所有點的最短路一定都在樹上,剩余圖就是這個最小生成樹。我試了試都是可以AC的。
開始初始化錯了,少初始化了一堆東西,dfs停不下來,MLE。后來wa,因為枚舉邊端點dp計數沒想清。
AC代碼
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std
;
const int modd
=1e9+7;
const int oo
=1e9+10;
const int NN
=100100;
const int MM
=200100;
int n
,m
;
int vis
[NN
],dis
[NN
];
struct edge
{int to
,cost
,from
;
}e
[MM
*2];
vector
<int> con
[NN
];
int a
[NN
];
struct point
{int id
;long long d
;
};
struct point_cmp
{bool
operator() (const point
&x
,const point
&y
)const{if(x
.d
>y
.d
)return 1;if(x
.d
==y
.d
&& x
.id
>y
.id
)return 1;return 0;}
};
priority_queue
<point
,vector
<point
> , point_cmp
> q
;
int pre
[NN
];
void dij(int origin
){for(int i
=0;i
<=n
+1;i
++)dis
[i
]=oo
;dis
[origin
]=0;point st
;st
.id
=origin
;st
.d
=0;q
.push(st
);while(!q
.empty()){point root
=q
.top();q
.pop();if(dis
[root
.id
]!=root
.d
)continue;for(int i
=0;i
<con
[root
.id
].size();i
++){edge ed
=e
[con
[root
.id
][i
]];int nex
=ed
.to
;if(dis
[nex
]>max(dis
[root
.id
],ed
.cost
) ){pre
[nex
]=con
[root
.id
][i
];dis
[nex
]=max(dis
[root
.id
],ed
.cost
);point neww
;neww
.id
=nex
;neww
.d
=dis
[nex
];q
.push(neww
);}}}
}
long long siz
[NN
],sizfa
[NN
],numson1
[NN
],numfa1
[NN
],num1
;
int f
[MM
];
void dfs(int cur
,int fa
){int up
=con
[cur
].size();numson1
[cur
]=(a
[cur
]==1);siz
[cur
]=1;for(int i
=0;i
<up
;i
++){edge ed
=e
[con
[cur
][i
]];int nex
=ed
.to
;if(f
[con
[cur
][i
]]&&nex
!=fa
){dfs(nex
,cur
);siz
[cur
]+=siz
[nex
];numson1
[cur
]+=numson1
[nex
];}}
}
long long ans
=0;
long long quan
[MM
];
void dfsfa(int cur
,int fa
,int co
){int up
=con
[cur
].size();numfa1
[cur
]=num1
-numson1
[cur
];sizfa
[cur
]=n
-siz
[cur
];if(cur
!=1){ans
+=quan
[co
]*(1ll*numfa1
[cur
]*(siz
[cur
]-numson1
[cur
])%modd
+1ll*(sizfa
[cur
]-numfa1
[cur
])*numson1
[cur
]%modd
)%modd
;ans
%=modd
;}for(int i
=0;i
<up
;i
++){edge ed
=e
[con
[cur
][i
]];int nex
=ed
.to
;if(f
[con
[cur
][i
]]&&nex
!=fa
){dfsfa(nex
,cur
,ed
.cost
);}}
}
int fa
[NN
];
int getf(int x
){if(fa
[x
]==x
)return x
;return (fa
[x
]=getf(fa
[x
]));
}
int main(){quan
[0]=1;for(int i
=1;i
<=200000;i
++){quan
[i
]=(quan
[i
-1]<<1)%modd
;}int t
;scanf("%d",&t
);while(t
--){scanf("%d%d",&n
,&m
);if(n
==0)break;for(int i
=1;i
<=n
;i
++)con
[i
].clear(),fa
[i
]=i
;for(int i
=0;i
<=m
*2;i
++)f
[i
]=0;num1
=0;for(int i
=1;i
<=n
;i
++){scanf("%d",a
+i
);num1
+=(a
[i
]==1);}int nume
=-1;for(int i
=1;i
<=m
;i
++){int x
,y
;scanf("%d%d",&x
,&y
);e
[++nume
].to
=y
;e
[nume
].cost
=i
;e
[nume
].from
=x
;con
[x
].push_back(nume
);e
[++nume
].to
=x
;e
[nume
].cost
=i
;e
[nume
].from
=y
;con
[y
].push_back(nume
);}dij(1);for(int i
=1;i
<=n
;i
++){f
[pre
[i
]]=1;f
[pre
[i
]^1]=1;}dfs(1,-1);ans
=0;dfsfa(1,-1,0);printf("%lld\n",ans
);}return 0;
}
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std
;
const int modd
=1e9+7;
const int oo
=1e9+10;
const int NN
=100100;
const int MM
=200100;
int n
,m
;
struct edge
{int to
,cost
,from
;
}e
[MM
*2];
vector
<int> con
[NN
];
int a
[NN
];
long long siz
[NN
],sizfa
[NN
],numson1
[NN
],numfa1
[NN
],num1
;
int f
[MM
];
void dfs(int cur
,int fa
){int up
=con
[cur
].size();numson1
[cur
]=(a
[cur
]==1);siz
[cur
]=1;for(int i
=0;i
<up
;i
++){edge ed
=e
[con
[cur
][i
]];int nex
=ed
.to
;if(f
[con
[cur
][i
]]&&nex
!=fa
){dfs(nex
,cur
);siz
[cur
]+=siz
[nex
];numson1
[cur
]+=numson1
[nex
];}}
}
long long ans
=0;
long long quan
[MM
];
void dfsfa(int cur
,int fa
,int co
){int up
=con
[cur
].size();numfa1
[cur
]=num1
-numson1
[cur
];sizfa
[cur
]=n
-siz
[cur
];if(cur
!=1){ans
+=quan
[co
]*(1ll*numfa1
[cur
]*(siz
[cur
]-numson1
[cur
])%modd
+1ll*(sizfa
[cur
]-numfa1
[cur
])*numson1
[cur
]%modd
)%modd
;ans
%=modd
;}for(int i
=0;i
<up
;i
++){edge ed
=e
[con
[cur
][i
]];int nex
=ed
.to
;if(f
[con
[cur
][i
]]&&nex
!=fa
){dfsfa(nex
,cur
,ed
.cost
);}}
}
int fa
[NN
];
int getf(int x
){if(fa
[x
]==x
)return x
;return (fa
[x
]=getf(fa
[x
]));
}
int main(){quan
[0]=1;for(int i
=1;i
<=200000;i
++){quan
[i
]=(quan
[i
-1]<<1)%modd
;}int t
;scanf("%d",&t
);while(t
--){scanf("%d%d",&n
,&m
);if(n
==0)break;for(int i
=1;i
<=n
;i
++)con
[i
].clear(),fa
[i
]=i
;for(int i
=0;i
<=m
*2;i
++)f
[i
]=0;num1
=0;for(int i
=1;i
<=n
;i
++){scanf("%d",a
+i
);num1
+=(a
[i
]==1);}int nume
=-1;for(int i
=1;i
<=m
;i
++){int x
,y
;scanf("%d%d",&x
,&y
);e
[++nume
].to
=y
;e
[nume
].cost
=i
;e
[nume
].from
=x
;con
[x
].push_back(nume
);e
[++nume
].to
=x
;e
[nume
].cost
=i
;e
[nume
].from
=y
;con
[y
].push_back(nume
);}for(int i
=0;i
<=nume
;i
+=2){int fx
=getf(e
[i
].from
);int fy
=getf(e
[i
].to
);if(fx
!=fy
){fa
[fx
]=fy
;f
[i
]=1;f
[i
^1]=1;}}dfs(1,-1);ans
=0;dfsfa(1,-1,0);printf("%lld\n",ans
);}return 0;
}
總結
以上是生活随笔為你收集整理的hdu6832(2020hdu多校6t6)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。