QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#136844 | #239. Maximum Weighted Matching | PlentyOfPenalty# | 100 ✓ | 916ms | 44188kb | C++20 | 4.5kb | 2023-08-09 12:41:45 | 2023-08-09 12:41:48 |
Judging History
answer
#include<bits/stdc++.h>
#define log(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const int N=2e5+9,mod=1e9+7;
int T,n,m,tot;
enum type{
normal,
series, //串联
parallel, //并联
};
struct edge{
int u,v,w,x,y;
type t;
}e[N];
struct atom{
long long sum;
int cnt;
friend constexpr atom operator|(const atom &a,const atom &b){
if(a.sum>b.sum)return a;
if(a.sum<b.sum)return b;
return {a.sum,(a.cnt+b.cnt)%mod};
}
friend constexpr atom operator+(const atom &a,const atom &b){
return {a.sum+b.sum,(int)((long long)a.cnt*b.cnt%mod)};
}
}dp[N][2][2];
map<int,int> G[N];
set<int> deg2;
queue<tuple<int,int,int>> multi;
int newnode(type t,int u,int v,int x,int y){
++tot;
e[tot].u=u,e[tot].v=v;
e[tot].x=x,e[tot].y=y;
e[tot].t=t;
return tot;
}
void link(int u,int v,int x){
// log("link %d %d %d\n",u,v,x);
if(G[u].find(v)!=G[u].end()){
multi.push({u,v,x});
}else{
if(G[u].size()==2)deg2.erase(u);
if(G[v].size()==2)deg2.erase(v);
G[u][v]=G[v][u]=x;
// log("u=%d v=%d su=%d sv=%d\n",u,v,(int)G[u].size(),(int)G[v].size());
if(G[u].size()==2)deg2.insert(u);
if(G[v].size()==2)deg2.insert(v);
}
// cerr<<"size: ";for(int i=1;i<=n;i++)cerr<<G[i].size()<<" \n"[i==n];
// cerr<<"deg2: ";for(int x:deg2)cerr<<x<<" ";cerr<<endl;
}
void merge_series(int t){
// log("merge series %d\n",t);
assert(G[t].size()==2);
auto [u,x]=*G[t].begin();
auto [v,y]=*G[t].rbegin();
deg2.erase(t);
G[t].clear();
if(G[u].size()==2)deg2.erase(u);
if(G[v].size()==2)deg2.erase(v);
G[u].erase(G[u].find(t));
G[v].erase(G[v].find(t));
if(G[u].size()==2)deg2.insert(u);
if(G[v].size()==2)deg2.insert(v);
int z=newnode(series,u,v,x,y);
link(u,v,z);
}
void merge_parallel(int u,int v,int x){
// log("merge parallel %d %d %d\n",u,v,x);
int y=G[u][v];
int z=newnode(parallel,u,v,x,y);
G[u][v]=G[v][u]=z;
}
inline void debug(int x){
log("dp[%d]: ..%lld .x%lld x.%lld xx%lld\n",x,dp[x][0][0].sum,dp[x][0][1].sum,dp[x][1][0].sum,dp[x][1][1].sum);
}
void dfs(int z){
// log("dfs[z=%d] x=%d y=%d u=%d v=%d\n",z,e[z].x,e[z].y,e[z].u,e[z].v);
if(e[z].t==normal){
dp[z][0][0]={0,1};
dp[z][1][1]={(long long)e[z].w,1};
}else{
int x=e[z].x,y=e[z].y,u=e[z].u,v=e[z].v;
if(e[z].t==parallel){
if(e[x].u!=e[z].u)swap(e[x].u,e[x].v);
if(e[y].u!=e[z].u)swap(e[y].u,e[y].v);
dfs(x);
dfs(y);
dp[z][0][0]=dp[x][0][0]+dp[y][0][0];
dp[z][0][1]=dp[x][0][1]+dp[y][0][0]|dp[x][0][0]+dp[y][0][1];
dp[z][1][0]=dp[x][1][0]+dp[y][0][0]|dp[x][0][0]+dp[y][1][0];
dp[z][1][1]=dp[x][1][1]+dp[y][0][0]|dp[x][0][0]+dp[y][1][1]|dp[x][0][1]+dp[y][1][0]|dp[x][1][0]+dp[y][0][1];
// log("PAR z[%d][u=%d v=%d] x[%d][u=%d v=%d] y=[%d][u=%d v=%d]\n",z,e[z].u,e[z].v,x,e[x].u,e[x].v,y,e[y].u,e[y].v);
// debug(x),debug(y),debug(z);
}else if(e[z].t==series){
if(e[x].u!=e[z].u&&e[x].v!=e[z].u){
swap(e[z].x,e[z].y);
swap(x,y);
}
if(e[x].u!=e[z].u)swap(e[x].u,e[x].v);
if(e[y].v!=e[z].v)swap(e[y].u,e[y].v);
dfs(x);
dfs(y);
dp[z][0][0]=dp[x][0][0]+dp[y][0][0]|dp[x][0][1]+dp[y][0][0]|dp[x][0][0]+dp[y][1][0];
dp[z][1][0]=dp[x][1][0]+dp[y][0][0]|dp[x][1][1]+dp[y][0][0]|dp[x][1][0]+dp[y][1][0];
dp[z][0][1]=dp[x][0][0]+dp[y][0][1]|dp[x][0][1]+dp[y][0][1]|dp[x][0][0]+dp[y][1][1];
dp[z][1][1]=dp[x][1][0]+dp[y][0][1]|dp[x][1][1]+dp[y][0][1]|dp[x][1][0]+dp[y][1][1];
// log("SER z[%d][u=%d v=%d] x[%d][u=%d v=%d] y=[%d][u=%d v=%d]\n",z,e[z].u,e[z].v,x,e[x].u,e[x].v,y,e[y].u,e[y].v);
// debug(x),debug(y),debug(z);
}
}
}
int main(){
#ifdef memset0
freopen("E.in","r",stdin);
#endif
ios::sync_with_stdio(0),cin.tie(0);
cin>>T;
while(T--){
cin>>n>>m,tot=m;
for(int i=1;i<=n;i++)G[i].clear();
// cerr<<"! "<<n<<" "<<m<<endl;
for(int u,v,w,i=1;i<=m;i++){
cin>>u>>v>>w;
e[i].u=u;
e[i].v=v;
e[i].w=w;
e[i].t=normal;
link(u,v,i);
}
while(tot<m*2-1){
if(multi.size()){
auto [u,v,x]=multi.front();
multi.pop();
merge_parallel(u,v,x);
}else if(deg2.size()){
merge_series(*deg2.begin());
}
// for(int u=1;u<=n;u++)
// for(auto [v,w]:G[u]){
// log("%d->%d:%d\n",u,v,w);
// }
}
// assert(multi.empty());
// assert(deg2.empty());
for(int i=1;i<=tot;i++){
for(int x=0;x<2;x++)
for(int y=0;y<2;y++){
dp[i][x][y].sum=-1e16;
dp[i][x][y].cnt=0;
}
}
dfs(tot);
atom ans={0ll,0};
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
ans=ans|dp[tot][i][j];
cout<<ans.sum<<" "<<ans.cnt<<'\n';
}
}
詳細信息
Test #1:
score: 100
Accepted
time: 916ms
memory: 44188kb
input:
6676 6 10 6 1 1 6 4 1 4 1 1 6 5 1 5 1 1 6 3 1 3 2 1 2 4 1 6 4 1 4 1 1 7 10 4 2 1 4 1 1 1 2 1 1 6 1 6 2 1 1 3 1 3 2 1 1 5 1 5 7 1 7 2 1 7 10 5 3 1 5 7 1 7 2 1 2 3 1 2 1 1 1 4 1 4 3 1 5 6 1 6 7 1 2 3 1 7 10 3 5 1 3 4 1 4 2 1 2 5 1 2 6 1 6 5 1 2 7 1 7 5 1 2 1 1 1 6 1 7 10 5 1 1 5 3 1 3 2 1 2 1 1 2 7 1 ...
output:
3 5 3 6 3 14 3 10 3 11 2 13 2 16 3 6 3 3 3 9 2 9 2 14 4 5 3 10 3 13 3 4 3 5 3 14 3 5 2 15 3 10 3 3 3 3 3 14 2 3 3 6 3 3 3 6 3 11 3 17 3 7 3 2 3 6 3 13 3 9 3 11 3 14 3 6 3 2 2 2 2 11 4 4 3 6 3 6 3 5 3 11 2 10 3 5 4 5 2 18 3 13 3 5 3 3 3 12 3 9 2 11 3 2 3 3 3 4 2 7 3 3 3 3 3 2 3 8 3 10 2 15 3 3 3 12 3...
result:
ok 6676 lines