1 const int N=55,M=1551;
2 int n,m;
3 int e[N][N];
4 struct node{
5 int x,y,z;
6 }edge[M];
7 bool mark[M];
8 int cnt,ver[M],nxt[M],h[N],w[N],fa[N],eid[N],dep[N],id[N];
9 namespace Graph{
10 int cnt=1,ver[M<<6],nxt[M<<6],w[M<<6],c[M<<6],h[M<<1],s,t;
11 inline void add_edge(int x,int y,int z,int cost){
12 // cout<<x<<" "<<y<<" "<<cost<<endl;
13 cnt++;ver[cnt]=y;nxt[cnt]=h[x];h[x]=cnt;w[cnt]=z;c[cnt]=cost;
14 cnt++;ver[cnt]=x;nxt[cnt]=h[y];h[y]=cnt;w[cnt]=0;c[cnt]=-cost;
15 }
16 int flow[M<<1],dis[M<<1],lst[M<<1],pre[M<<1];
17 bool vis[M<<1];
18 inline bool bfsmax(){
19 queue<int>q;
20 memset(dis,0xc0,sizeof(dis));
21 memset(flow,0x3f,sizeof(flow));
22 memset(vis,0,sizeof(vis));
23 q.push(s);vis[s]=1,dis[s]=0,pre[t]=-1;
24 while(q.size()){
25 int x=q.front();
26 q.pop();
27 vis[x]=0;
28 for(int i=h[x];i;i=nxt[i]){
29 int y=ver[i];
30 if(w[i]>0&&dis[y]<dis[x]+c[i]){
31 dis[y]=dis[x]+c[i];
32 pre[y]=x;lst[y]=i;
33 flow[y]=min(w[i],flow[x]);
34 if(!vis[y]){
35 vis[y]=1;
36 q.push(y);
37 }
38 }
39 }
40 }
41 return pre[t]!=-1;
42 }
43 inline int getmax(){
44 int maxc=0;
45 while(bfsmax()){
46 if(dis[t]<0)break;
47 maxc+=flow[t]*dis[t];
48 int cur=t;
49 while(cur!=s){
50 w[lst[cur]]-=flow[t];
51 w[lst[cur]^1]+=flow[t];
52 cur=pre[cur];
53 }
54 }
55 return maxc;
56 }
57 inline int solve(){
58 s=0,t=m+1;
59 for(int i=1;i<n;i++)add_edge(s,i,1,0);
60 for(int i=n;i<=m;i++)add_edge(i,t,1,0);
61 return getmax();
62 }
63 }
64 inline void add_edge(int x,int y,int z){cnt++;ver[cnt]=y;nxt[cnt]=h[x];h[x]=cnt;w[cnt]=z;}
65 inline void dfs(int x){
66 dep[x]=dep[fa[x]]+1;
67 for(int i=h[x];i;i=nxt[i]){
68 int y=ver[i];
69 if(y!=fa[x]){
70 fa[y]=x;
71 eid[y]=w[i];
72 dfs(y);
73 }
74 }
75 }
76 inline void modify(int x,int y,int z){
77 if(dep[x]<dep[y])swap(x,y);
78 while(dep[x]>dep[y]){
79 Graph::add_edge(id[eid[x]],id[z],1,edge[eid[x]].z-edge[z].z);
80 x=fa[x];
81 }
82 while(x^y){
83 Graph::add_edge(id[eid[x]],id[z],1,edge[eid[x]].z-edge[z].z);
84 Graph::add_edge(id[eid[y]],id[z],1,edge[eid[y]].z-edge[z].z);
85 x=fa[x],y=fa[y];
86 }
87 }
88 int main(){
89 ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
90 cin>>n>>m;
91 for(int i=1;i<=m;i++){
92 int x,y,z;
93 cin>>x>>y>>z;
94 e[x][y]=e[y][x]=i;
95 edge[i]=(node){x,y,z};
96 }
97 for(int i=1;i<n;i++){
98 int x,y;
99 cin>>x>>y;
100 mark[e[x][y]]=1;
101 add_edge(x,y,e[x][y]);add_edge(y,x,e[x][y]);
102 }
103 for(int i=1,t1=0,t2=n-1;i<=m;i++){
104 if(mark[i])id[i]=++t1;
105 else id[i]=++t2;
106 }
107 dfs(1);
108 for(int i=1;i<=m;i++){
109 if(!mark[i]){
110 int x=edge[i].x,y=edge[i].y;
111 modify(x,y,i);
112 }
113 }
114 cout<<Graph::solve()<<endl;
115 return 0;
116 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】