CCPC-Wannafly Summer Camp 2019 Day1 (无 I 题)

 比赛链接:https://vjudge.net/contest/312902#overview

目录

A - Jzzhu and Cities

B - Phillip and Trains

C - A Mist of Florescence

D - Unbearable Controversy of Being

 E - Igor In the Museum

F - The Child and Toy

G - New Year Permutation

H - Alyona and the Tree

J - Resort

 K - Royal Questions

L - Love Triangle

M - Bakery

N - News Distribution

O - NP-Hard Problem

 



A - Jzzhu and Cities

 将火车边考虑为特殊边,如果到特殊边的最短路要小于特殊边权值,显然可以删去,在等于的时候考虑到此点的入度如果大于1,则也可删去

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 2e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e9;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,m,k,res[maxn],in[maxn];
vector< pair<ll,ll> >G[maxn],T[5];
bool flag[maxn];

struct node
{
	ll now,sum;
	node(ll a,ll b)
	{
		now = a;
		sum = b;
	}
	
	bool operator < (const node t) const
	{
		return sum > t.sum;
	}
};

void dij(ll be)
{
	priority_queue<node>Q;
	Q.push( node(be,0) );
	//flag[be] = true; 
	
	while(!Q.empty())
	{
		node tmp = Q.top();
		Q.pop();
		
		
		
		if(flag[tmp.now])
			continue;
			
		flag[tmp.now] = true;
		
		for(ll i = 0; i < G[tmp.now].size(); i++)
		{
			ll to = G[tmp.now][i].first, cost = G[tmp.now][i].second;
			
			if(cost+res[tmp.now] == res[to])
			{	
				in[to]++;
			}
			else if(cost+res[tmp.now] < res[to])
			{
				in[to] = 1;
				res[to] = cost+res[tmp.now];
			}
				
			if(!flag[to])
			{	
				//flag[to] = true;			
				Q.push( node(to,tmp.sum+cost) );
			}	
		}	
	}
	
	return ;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0); 
	
	cin >> n >> m >> k;
	
	for(ll i = 2; i <= n; i++)
		res[i] = inf;
	
	for(ll i = 1; i <= m; i++)
	{
		ll a,b,c;
		cin >> a >> b >> c;
		
		G[a].push_back(make_pair(b,c));
		G[b].push_back(make_pair(a,c));	
	}
	
	for(ll i = 1; i <= k; i++)
	{
		ll a,b;
		cin >> a >> b;
		
		G[1].push_back(make_pair(a,b));
		G[a].push_back(make_pair(1,b));
		
		T[1].push_back(make_pair(a,b));
	}
	
	dij(1);
	
	//for(ll i = 1; i <= n; i++)
	//	cout << in[i] << " ";
	
	ll ans = 0;
	for(ll i = 0; i < T[1].size(); i++)
	{
		ll to = T[1][i].first, cost = T[1][i].second;
		
		if(cost > res[to])
		{	
			ans++;	
		}
		else if( cost == res[to] && in[to] > 1)
		{
			in[to]--;
			ans++;
		}
	}
	
	cout << ans << endl; 
	
	return 0;
	
}

B - Phillip and Trains

 将题目通过相对位移转化为是否能到达最后一列的走迷宫问题,(过程中的每一步都要判断能否到达)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 2e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e9;
const ld eps = 1e-5;
const ld e = exp(1);

bool flag;
ll T,n,k,cnt,dx[3] = {0,1,-1},dy[3] = {0,0,0};
char str[5][150];
bool f[5][150];

struct node
{
	ll x,y;
	node(ll a,ll b)
	{
		x = a;
		y = b;
	}
	
};

void slove(ll bex,ll bey)
{
	queue<node>Q;
	Q.push( node(bex,bey) );
	//f[bex][bey] = 1;
	
	while(!Q.empty())
	{
		node tmp = Q.front();
		Q.pop();
		
		//cout << tmp.x << " " << tmp.y << endl;
		
		
		if(tmp.y >= n)
		{
			flag = true;
			return ;
		}
		
		//cout << f[tmp.x][tmp.y] << " " << tmp.x << " " << tmp.y << endl;
		if( !f[tmp.x][tmp.y] )
		{
			//cout << "kakak" << endl;
			
			f[tmp.x][tmp.y] = 1;
			
			ll tx = tmp.x,ty = tmp.y+1;
			
			if(tx >= 1 && tx <= 3 && ty >= 1 && ty <= n+3 && str[tx][ty] != '*')
			{
				for(ll i = 0; i < 3; i++)
				{
					ll ttx = tx+dx[i],tty = ty;
					
					if(ttx >= 1 && ttx <= 3 && tty >= 1 && tty <= n+3 && str[ttx][tty] != '*' && str[ttx][tty+1] != '*' && str[ttx][tty+2] != '*' )
					{						
						Q.push( node(ttx,tty+2) );
					}
				}
			}
			
		}
			
		
		
	}
	
	return ;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	
	cin >> T;
	while(T--)
	{
		memset(f,false,sizeof(f));
		flag = false;
		ll bex,bey;
		cin >> n >> k;
		
		for(ll i = 1; i <= 3; i++)
		{
			cin >> str[i]+1;
			
			for(ll j = 1; j <= n; j++)
			{
				if(str[i][j] == 's')
				{
					bex = i;
					bey = j;
				}
				else if(str[i][j] != '.')
				{
					str[i][j] = '*';
				}
			}
			
			for(ll j = n; j <= n+5; j++)
			{
				str[i][j] = '.';
			}
			
		}
		
		slove(bex,bey);
		
		if(flag)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
		
	}
	
	return 0;
}
	

C - A Mist of Florescence

构造问题,考虑后可得出一定有 50 x 50的网格符合题意,那么我们将表格分成A,B,C,D四份,在A中插D,B中插C,C中插B,D中插A即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e3+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

ll a,b,c,d,n,m;
char str[55][55];

void init()
{
	for(ll i = 1; i <= 50; i++)
	{
		for(ll j = 1; j <= 50; j++)
		{
			if(i <= 25 && j <= 25)
				str[i][j] = 'A';
			else if(i <= 25 && j > 25)
				str[i][j] = 'B';
			else if(i > 25 && j <=25)
				str[i][j] = 'C';
			else
				str[i][j] = 'D';
		}
	}
	return ;
}

int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> a >> b >> c >> d;
	
	init();
	
	
	for(ll i = 1; i <= 25 && d > 1; i += 2)
	{
		for(ll j = 1; j <= 25 && d > 1; j += 2)
		{
			str[i][j] = 'D';
			d--;
		}
	}
	
	for(ll i = 1; i <= 25 && c > 1; i += 2)
	{
		for(ll j = 26; j <= 50 && c > 1; j += 2)
		{
			str[i][j] = 'C';
			c--;
		}
	}
	
	for(ll i = 26; i <= 50 && b > 1; i += 2)
	{
		for(ll j = 1; j <= 25 && b > 1; j += 2)
		{
			str[i][j] = 'B';
			b--;
		}
	}
	
	for(ll i = 26; i <= 50 && a > 1; i += 2)
	{
		for(ll j = 26; j <= 50 && a > 1; j += 2)
		{
			str[i][j] = 'A';
			a--;
		}
	}
	
	cout << 50 << " " << 50 << endl;
	for(ll i = 1; i <= 50; i++)
	{
		for(ll j = 1; j <= 50; j++)
		{
			cout << str[i][j];
		}
		cout << endl;
	}
		
	
	return 0;
}

 

D - Unbearable Controversy of Being

题意就是找出有多少个菱形,dfs搜出每个点走两步到达的点,用数组记录次数,然后通过组合数计算出答案即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 3e3+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

vector<ll>G[maxn];
ll n,m,ans;
ll arr[maxn][maxn];
ll num[maxn][maxn];
bool use[maxn];

struct node
{
	ll now,cost;
	node(ll a,ll b)
	{
		now = a;
		cost = b;
	}
	
	bool operator < (const node t) const
	{
		return cost > t.cost;
	}
};

ll fac[maxn]={1,1},inv[maxn]={1,1},f[maxn]={1,1};
ll C(ll a,ll b){
    if(b>a)return 0;
    return fac[a]*inv[b]%mod*inv[a-b]%mod;
}
void init(){//快速计算阶乘的逆元
    for(int i=2;i<maxn;i++){
        fac[i]=fac[i-1]*i%mod;
        f[i]=(mod-mod/i)*f[mod%i]%mod;
        inv[i]=inv[i-1]*f[i]%mod;
    }
}


ll dfs(ll be,ll now,ll step)
{
	//cout << be << " " << now << " " << step << endl;
	if(step == 2)
	{
		//cout << be << " " << now << endl; 
		num[be][now]++;
		return 0;
	}
	
	for(ll i = 0; i < G[now].size(); i++)
	{
		ll to = G[now][i];
		
		if(to != be)
			dfs(be,to,step+1);
	}
	
	return 0;
}



int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	init();
	
	cin >> n >> m;
	for(ll i = 1; i <= m; i++)
	{
		ll u,v;
		cin >> u >> v;
		arr[u][v] = 1;	
		G[u].push_back(v);
	}
	
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++)
		{
			if(i!=j)
				arr[i][j] = inf;
		}
	}
	
	for(ll i = 1; i <= n; i++)
	{
		dfs(i,i,0);
	}
	
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++)
		{
			if(num[i][j] >= 2)
			{
				//cout << i << " " << j << endl;
				//cout << be << " " << en << " " << num[be][en] << endl;
				ans += C(num[i][j],2);
			}
		}		
	}
	
	cout << ans << endl;
	
	return 0;
}

 E - Igor In the Museum

联通块染色,O(1)输出即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e3+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e9;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,m,k,cnt,ans;
char str[maxn][maxn];
bool fnode[maxn][maxn];
ll dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
bool fstr[maxn][maxn];
ll t[maxn][maxn];
ll res[maxn*maxn];

struct Why
{
	ll x,y;
	
	Why(ll a,ll b)
	{
		x = a;
		y = b;
	}
};

void slove(ll x,ll y)
{
	queue<Why>Q;
	
	Q.push( Why(x,y) );
	fnode[x][y] = 1;
	t[x][y] = ++cnt;
	fstr[x][y] = 1;
	
	while(!Q.empty())
	{
		Why tmp = Q.front();
		Q.pop();
		t[tmp.x][tmp.y] = cnt;
		fstr[tmp.x][tmp.y] = 1;
		
		for(ll i = 0; i < 4; i++)
		{
			ll tx = dx[i]+tmp.x,ty = dy[i]+tmp.y;
			
			if(str[tx][ty] == '*')
				ans++;
			
			if(str[tx][ty] == '.' && fnode[tx][ty] == false)
			{
				
				fnode[tx][ty] = true;
				Q.push( Why(tx,ty) );
			}
		}
	}
	return ;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0); 
	
	cin >> n >> m >> k;
	
	for(ll i = 1; i <= n; i++)
	{
		cin >> str[i]+1;
	}
	
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= m; j++)
		{
			if(str[i][j] == '.' && fstr[i][j] == false )
			{
				ans = 0;
				slove(i,j);
				res[cnt] = ans;
			}
		}
	}
	
	while(k--)
	{
		
		ll x,y;
		cin >> x >> y;
	
		cout << res[ t[x][y] ] << endl;
	}
	
	return 0;
	
}

F - The Child and Toy

遍历边取最小值累加即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e3+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,m,arr[maxn],ans;
vector<ll>G[maxn];
bool flag[maxn][maxn];

int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n >> m;
	
	memset(flag,1,sizeof(flag));
	
	for(ll i = 1; i <= n; i++)
	{
		cin >> arr[i];
	}
	
	for(ll i = 1; i <= m; i++)
	{
		ll u,v;
		cin >> u >> v;
		
		G[u].push_back(v);
		G[v].push_back(u);
	}
	
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 0; j < G[i].size(); j++)
		{
			ll now = i,to = G[i][j];
			
			if(flag[now][to] == 1)
			{
				ans += min(arr[now],arr[to]);
				flag[now][to] = 0;
				flag[to][now] = 0;
			}
				
			
		}
	}
	
	
	cout << ans << endl;
	
	
		
	
	return 0;
}

G - New Year Permutation

并查集维护联通块,同一联通块内的任意点均可交换,在原数组的基础上按每一联通块内部从小到大输出即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 3e2+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,p[maxn],fa[maxn];
char str[maxn][maxn];
vector<ll>V[maxn];
ll len;
bool use[maxn];

ll fi(ll x)
{
	return fa[x] == x? x: fa[x] = fi(fa[x]);
}

int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n;
	for(ll i = 1; i <= n; i++)
	{
		cin >> p[i];
		fa[i] = i;
	}

	for(ll i = 1; i <= n; i++)
	{
		cin >> str[i]+1;
	}
	
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++)
		{
			if(str[i][j] == '1')
			{
				fa[ fi(i) ] = fi( j );
			}
		}
	}
	
	for(ll i = 1; i <= n; i++)
	{
		fi(i);
	}
	
	for(ll i = 1; i <= n; i++)
	{
		
		if(!use[i])
			V[++len].push_back(i);
			
		for(ll j = i+1; j <= n; j++)
		{
			if(!use[j] && fa[i] == fa[j])
			{
				use[j] = true;
				V[len].push_back(j);	
			}
		}
	}
	
//	for(ll i = 1; i <= len; i++)
//	{
//		for(ll j = 0; j < V[i].size(); j++)
//			cout << V[i][j] << " ";
//		cout << endl;
//	}
	
	for(ll i = 1; i <= len; i++)
	{
		vector<ll>t;
		for(ll j = 0; j < V[i].size(); j++)
		{
			t.push_back(p[V[i][j]]);	
		} 
		sort(t.begin(),t.end());
		
		for(ll j = 0; j < t.size(); j++)
		{
			p[V[i][j]] = t[j];
		}
	}
	
	for(ll i = 1; i <= n; i++)
		cout << p[i] << " ";
	cout << endl;
	

	
	return 0;
}

H - Alyona and the Tree

搜索删除特殊点即可,需要注意,如果非叶子节点为特殊点,则为了删除此点,此点的子树都需删除

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);
 
ll n,node[maxn],ans;
vector< pair<ll,ll> >G[maxn];
bool use[maxn];
 
 
ll dfs(ll now,ll sum)
{
	if(now > n)
		return 0;
	if(sum > node[now])
	{
		return 0;
	}
	
	use[now] = true;
	
	for(ll i = 0; i < G[now].size(); i++)
	{
		ll to = G[now][i].first,cost = G[now][i].second;
		
		if(!use[to])
		{
			dfs(to,max(cost,cost+sum) );
			
		}
	}
	
	return 0;
}
 
 
int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n;
	
	for(ll i = 1; i <= n; i++)
	{
		cin >> node[i];
	}
	
	for(ll i = 2; i <= n; i++)
	{
		ll u,v,w;
		u = i;
		cin >> v >> w;
				
		G[u].push_back(make_pair(v,w));
		G[v].push_back(make_pair(u,w));
	}
	
	
	
	dfs(1,0);
	
	for(ll i = 2; i <= n; i++)
	{
		if(!use[i])
			ans++;
			
	}
	
	cout << ans << endl;
	
 
	return 0;
}

J - Resort

反向建边,从宾馆出发搜寻不分叉的最长路径

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,type[maxn],a[maxn],du[maxn],res;
vector<ll>G[maxn],ans[maxn];

ll dfs(ll be,ll now)
{

	for(ll i = 0; i < G[now].size(); i++)
	{
		ll to = G[now][i];
		
		if(du[to] == 1 && type[to] == 0)
		{
			ans[be].push_back(to);
			dfs(be,to);
		}
		else
		{
			return 0;
		}
	}
	
	return 0;
}

int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n;
	for(ll i = 1; i <= n; i++)
	{
		cin >> type[i];
	}
	
	for(ll i = 1; i <= n; i++)
	{
		cin >> a[i];
		
		if(a[i] > 0)
		{
			G[i].push_back(a[i]);
			du[a[i]]++;
		}
	}
	
	for(ll i = 1; i <= n; i++)
	{
		if(type[i] == 1)
		{
			ans[i].push_back(i);
			dfs(i,i);
			res = max( res, ll( ans[i].size() ) );
		}
	}
	
	//sort(ans.begin(),ans.end());
	cout << res<< endl;
	
	for(ll i = 1; i <= n; i++)
	{
		if(ans[i].size() == res)
		{
			for(ll j = ans[i].size()-1; j >= 0; j--)
				cout << ans[i][j] << " ";
			cout << endl;
			return 0;
		}
	}
	
	
	return 0;
}

 K - Royal Questions

此题将每个公主心仪的两个王子连边(方向不定), 权值则为公主的嫁妆,问题就变成了在每个点入度为1的情况下,搜寻最大的边权,可以发现最后建成的图为基环树森林,森林中最多一个环(多于一个环就会重婚),并查集判环,每选用一条边,就可以为边加定方向,魔改克鲁斯卡尔即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 2e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,m,fa[maxn],use[maxn],ans;
struct Why
{
	ll u,v,w;
}arr[maxn];

bool cmp(Why a,Why b)
{
	return a.w > b.w;
}

ll fi(ll x)
{
	return fa[x] == x? x : fa[x] = fi(fa[x]);
}

int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n >> m;
	
	for(ll i = 1; i <= m; i++)
	{
		cin >> arr[i].u >> arr[i].v >> arr[i].w;
	}
	
	sort(arr+1,arr+1+m,cmp);
	
	for(ll i = 1; i <= n; i++)
		fa[i] = i;
	
	for(ll i = 1; i <= m; i++)
	{
		ll f1 = fi(arr[i].u),f2 = fi(arr[i].v),cost = arr[i].w;
		
		if(f1 != f2)
		{
			if( !( use[f1] && use[f2]) )
			{	
				fa[f2] = f1;
				use[f1] = use[f1] | use[f2];
				ans += cost;
			}
		}
		else if(f1 == f2)
		{
			if(!use[f1])
			{
				use[f1] = true;
				ans += cost;
			}
			
		}
	}
	
	cout << ans << endl;
	
	
	
	
	
	return 0;
}

L - Love Triangle

O(n)判断是否有三元环即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e3+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e9;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,arr[6000];
bool flag = false;
bool G[5005][5005];
vector<ll>k[5005];

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0); 
	
	cin >> n;
	
	for(ll i = 1; i <= n; i++)
	{
		cin >> arr[i];
		G[i][ arr[i] ] = true;
		
		
	}
	
	for(ll i = 1; i <= n; i++)
	{
		ll t = arr[i];
		
		ll k = arr[t];
		
		ll tmp = arr[k];
		
		if(tmp == i)
		{
			cout << "YES" << endl;
			return 0;
		}
	}
	
	cout << "NO" << endl;
	
	
	return 0;
	
}

 

M - Bakery

遍历每条边,在一端为特殊点,一端为非特殊点时保存最小值即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);
 
ll n,m,k,node[maxn],ans = inf,du[maxn];
vector< pair<ll,ll> >G[maxn];
vector<ll>V;
bool flag[maxn];
 
int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n >> m >> k;
	
	for(ll i = 1; i <= m; i++)
	{
		ll u,v,w;
		cin >> u >> v >> w;
		
		G[u].push_back(make_pair(v,w));
		G[v].push_back(make_pair(u,w));
		
	}
	
	for(ll i = 1; i <= k; i++)
	{
		cin >> node[i];
		flag[node[i]] = true;
//		if(du[node[i]] != 0)
//		{
//			V.push_back(node[i]);
//		}
 
		
	}
	
		for(ll i = 1; i <= k; i++)
		{
			ll now = node[i];
			
			for(ll j = 0; j < G[now].size(); j++)
			{
				if(now != G[now][j].first && flag[ G[now][j].first ] == false)
					ans = min(ans,G[now][j].second);
			}
		}
		
		if(ans != inf)
			cout << ans << endl;
		else
			cout << -1 << endl;
	
	
	return 0;
}

 

N - News Distribution

并查集暴力

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
#define gcd __gcd
const ll maxn = 5e5+100;
const ll mod = 998244353;
//const ld pi = acos(-1.0);
const ll inf = 1e18;
//const ld eps = 1e-5;
//const ld e = exp(1);
ll n,m,fa[maxn],sum[maxn];
ll fi(ll x)
{
	return fa[x] == x? x : fa[x] = fi(fa[x]);
}

vector<ll>G[maxn];

int main()
{ 

	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);


	cin >> n >> m;


	for(ll i = 1; i <= n; i++)
	{
		fa[i] = i;
	}

	for(ll i = 1; i <= m; i++)
	{
		ll k,x,y;
		cin >> k;
		if(!k)

			continue;
		cin >> x;

		ll t1 = fi(x);

		for(ll j = 2; j <= k; j++)
		{
			cin >> y;

			ll t2 = fi(y);
			fa[t2] = t1;		
		}
	}
	for(ll i = 1; i <= n; i++)
	{
		ll t = fi(fa[i]);
		sum[t]++; 
	}

	for(ll i = 1; i <= n; i++)
	{
		ll tfa = fi(i);
		cout << sum[tfa] << " ";
	}
	cout << endl;
	return 0;
}

 

O - NP-Hard Problem

二分图染色,注意可能会有多个独立联通块,不要漏下

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 1e5+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);

ll n,m,arr[maxn];
vector<ll>G[maxn];
vector<ll>a,b;
bool flag = true;

void bfs(ll be)
{
	queue<ll>Q;
	Q.push(be);
	
	while(!Q.empty())
	{
		ll now = Q.front();
		Q.pop();
		
		for(ll i = 0; i < G[now].size(); i++)
		{
			ll to = G[now][i];
			
			if( arr[to] == -1 )
			{
				arr[to] = arr[now]^1;
				
				if(arr[to] == 0)
					a.push_back(to);
				else
					b.push_back(to);
				
				Q.push(to);
			}
			else if(arr[to] == arr[now] && to != now)
			{
				flag = false;	
				return ;
			}
		}
	}
	
	return ;
}

int main()
{	
    //ios::sync_with_stdio(false);
    //cin.tie(0),cout.tie(0);
	
	cin >> n >> m;
	
	for(ll i = 1; i <= n; i++)
		arr[i] = -1;
	
	for(ll i = 1; i <= m; i++)
	{
		ll u,v;
		cin >> u >> v;
		
		G[u].push_back(v);
		G[v].push_back(u);
	}
	
	arr[1] = 0;
	a.push_back(1);
	bfs(1);
	
	for(ll i = 2; i <= n; i++)
	{
		if(arr[i] == -1)
		{
			arr[i] = 0;
			a.push_back(i);
			
			bfs(i);
		}
	}
	
	if(flag)
	{

		cout << a.size() << endl;
		for(ll i = 0; i < a.size(); i++)
			cout << a[i] << " ";
		cout << endl;
		
		cout << b.size() << endl;
		for(ll i = 0; i < b.size(); i++)
			cout << b[i] << " ";
		cout << endl; 
	}
	else
		cout << -1 << endl;
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值