QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#136844#239. Maximum Weighted MatchingPlentyOfPenalty#100 ✓916ms44188kbC++204.5kb2023-08-09 12:41:452023-08-09 12:41:48

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-09 12:41:48]
  • 评测
  • 测评结果:100
  • 用时:916ms
  • 内存:44188kb
  • [2023-08-09 12:41:45]
  • 提交

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