QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#422089#239. Maximum Weighted Matchingship2077100 ✓1034ms37564kbC++142.8kb2024-05-26 18:56:282024-05-26 18:56:29

Judging History

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

  • [2024-05-26 18:56:29]
  • 评测
  • 测评结果:100
  • 用时:1034ms
  • 内存:37564kb
  • [2024-05-26 18:56:28]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int M=1e5+5,mod=1e9+7;
constexpr ll inf=0x3f3f3f3f3f3f3f3f;
struct info{ll val;int num;
	info(ll val_=0,int num_=0){val=val_;num=num_;}
};
struct node{
	info dp00,dp01,dp10,dp11;
	node(info dp00_=info(0,0),info dp01_=info(0,0),info dp10_=info(0,0),info dp11_=info(0,0))
		{dp00=dp00_;dp01=dp01_;dp10=dp10_;dp11=dp11_;}
	node rev(){return node(dp00,dp10,dp01,dp11);}
};
int rdc(int x){return x>=mod?x-mod:x;}
info operator +(info a,info b){return a.val==b.val?info(a.val,rdc(a.num+b.num)):a.val>b.val?a:b;}
info operator *(info a,info b){return info(a.val+b.val,1ll*a.num*b.num%mod);}
node operator +(node a,node b){return node(a.dp00+b.dp00,a.dp01+b.dp01,a.dp10+b.dp10,a.dp11+b.dp11);}
map<pair<int,int>,node>mp;
int n,m;set<int>adj[M];
int read(){
	int x=0;char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) x=x*10+ch-48,ch=getchar();
	return x;
}
void solve(){
	n=read();m=read();mp.clear();
	for (int i=1;i<=n;i++) adj[i].clear();
	for (int i=1;i<=m;i++){
		int x=read(),y=read(),z=read();
		adj[x].insert(y);adj[y].insert(x);
		if (!mp.count(minmax(x,y)))
			{mp[minmax(x,y)]=node(info(0,1),info(-inf,0),info(-inf,0),info(z,1));continue;}
		const info tmp=mp[minmax(x,y)].dp11;
		if (z>tmp.val) mp[minmax(x,y)]=node(info(0,1),info(-inf,0),info(-inf,0),info(z,1));
		else if (z==tmp.val) mp[minmax(x,y)]=node(info(0,1),info(-inf,0),info(-inf,0),info(z,tmp.num+1));
	} queue<int>q;
	for (int i=1;i<=n;i++)
		if (adj[i].size()==2)
			q.push(i);
	while (!q.empty()){
		int u=q.front();q.pop();
		if (adj[u].size()!=2) continue;
		int x=*adj[u].begin(),y=*adj[u].rbegin();
		adj[u].clear();
		adj[x].erase(u);adj[y].erase(u);
		adj[x].insert(y);adj[y].insert(x);
		if (adj[x].size()==2) q.push(x);
		if (adj[y].size()==2) q.push(y);
		node tmp1=mp[minmax(x,u)],tmp2=mp[minmax(u,y)];
		if (x>u) tmp1=tmp1.rev(); if (u>y) tmp2=tmp2.rev(); node tmp;
		tmp.dp00=tmp1.dp00*tmp2.dp00+tmp1.dp00*tmp2.dp10+tmp1.dp01*tmp2.dp00;
		tmp.dp01=tmp1.dp00*tmp2.dp01+tmp1.dp00*tmp2.dp11+tmp1.dp01*tmp2.dp01;
		tmp.dp10=tmp1.dp10*tmp2.dp00+tmp1.dp10*tmp2.dp10+tmp1.dp11*tmp2.dp00;
		tmp.dp11=tmp1.dp10*tmp2.dp01+tmp1.dp10*tmp2.dp11+tmp1.dp11*tmp2.dp01;
		if (mp.count(minmax(x,y))){
			node &res=mp[minmax(x,y)];
			res.dp11=res.dp11*tmp.dp00+res.dp10*tmp.dp01+res.dp01*tmp.dp10+res.dp00*tmp.dp11;
			res.dp10=res.dp10*tmp.dp00+res.dp00*tmp.dp10;
			res.dp01=res.dp01*tmp.dp00+res.dp00*tmp.dp01;
			res.dp00=res.dp00*tmp.dp00;
		}
		else mp[minmax(x,y)]=tmp;
	}
	for (int x=1;x<=n;x++)
		if (!adj[x].empty()){
			int y=*adj[x].begin();node tmp=mp[minmax(x,y)];
			info ans=tmp.dp00+tmp.dp01+tmp.dp10+tmp.dp11;
			return printf("%lld %d\n",ans.val,ans.num),void();
		}
}
int main(){int T=read();while (T--) solve();return 0;}

詳細信息

Test #1:

score: 100
Accepted
time: 1034ms
memory: 37564kb

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