hdu 6041 I Curse Myself 无向图找环+优先队列

时间:2024-06-21 17:07:20

I Curse Myself

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description
There is a connected undirected graph with weights on its edges. It is guaranteed that each edge appears in at most one simple cycle.

Assuming that the weight of a weighted spanning tree is the sum of weights on its edges, define V(k) as the weight of the k-th smallest weighted spanning tree of this graph, however, V(k) would be defined as zero if there did not exist k different weighted spanning trees.

Please calculate (∑k=1Kk⋅V(k))mod232.

Input
The input contains multiple test cases.

For each test case, the first line contains two positive integers n,m (2≤n≤1000,n−1≤m≤2n−3), the number of nodes and the number of edges of this graph.

Each of the next m lines contains three positive integers x,y,z (1≤x,y≤n,1≤z≤106), meaning an edge weighted z between node x and node y. There does not exist multi-edge or self-loop in this graph.

The last line contains a positive integer K (1≤K≤105).

Output
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
Sample Input
4 3
1 2 1
1 3 2
1 4 3
1
3 3
1 2 1
2 3 2
3 1 3
4
6 7
1 2 4
1 3 2
3 5 7
1 5 3
2 4 1
2 6 2
6 4 5
7
Sample Output
Case #1: 6
Case #2: 26
Case #3: 493
Source
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
#define PI acosI(-1.0)
typedef long long ll;
typedef pair<int,int> P;
const int maxn=1e3+,maxm=1e5+,inf=0x3f3f3f3f,mod=1e9+;
const ll INF=1e13+; struct is
{
int x,r;
bool operator <(const is &c)const
{
return x<c.x;
}
};
int d[maxn],n,m,k;
inline void update(vector<int>&a,vector<int>&b)
{
priority_queue<is>q;
for(int i=;i<b.size();i++)
d[i] = ,q.push((is){a[]+b[i],i});
vector<int>ans;
for(int i=;i<=k;i++)
{
if(q.empty())break;
is x=q.top();
q.pop();
ans.push_back(x.x);
if(d[x.r]+<a.size())
q.push((is){a[++d[x.r]]+b[x.r],x.r});
}
a=ans;
}
int cmp(int x,int y)
{
return x>y;
}
struct edge
{
int from,to,d,nex;
}G[maxn<<];
int head[maxn],edg;
inline void addedge(int u,int v,int d)
{
G[++edg]=(edge){u,v,d,head[u]},head[u]=edg;
G[++edg]=(edge){v,u,d,head[v]},head[v]=edg;
}
int pre[maxn],bccno[maxn];
int dfs_clock,bcc_cnt;
stack<int>s;
vector<int>ans,fuck;
inline int dfs(int u,int fa)
{
int lowu=++dfs_clock;
pre[u]=dfs_clock;
int child=;
for(int i=head[u]; i!=-; i=G[i].nex)
{
int v=G[i].to;
edge e=G[i];
if(!pre[v])
{
s.push(i);
child++;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u])
{
bcc_cnt++;
fuck.clear();
while(true)
{
int e=s.top();
s.pop();
fuck.push_back(G[e].d);
if(bccno[G[e].from]!=bcc_cnt)
bccno[G[e].from]=bcc_cnt;
if(bccno[G[e].to]!=bcc_cnt)
bccno[G[e].to]=bcc_cnt;
if(G[e].from==u&&G[e].to==v) break;
}
if(fuck.size()>)update(ans,fuck);
}
}
else if(pre[v]<pre[u]&&v!=fa)
{
s.push(i);
lowu=min(lowu,pre[v]);
}
}
return lowu;
}
void init()
{
dfs_clock=bcc_cnt=edg=;
for(int i=;i<=n;i++)
head[i]=-,bccno[i]=,pre[i]=;
ans.clear();
ans.push_back();
} int main()
{
int cas=;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
ll sumsum=;
for(int i=; i<=m; i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
sumsum+=z;
addedge(x,y,z);
}
scanf("%d",&k);
dfs(,-);
ll out=,MOD=(1LL<<);
printf("Case #%d: ",cas++); for(int i=;i<=k;i++)
{
if(i->=ans.size())break;
out+=1LL*(sumsum-ans[i-])*i;
out%=MOD;
}
printf("%lld\n",out);
}
return ;
}