初三高考放假做题记录part.1

luoguP3243 [HNOI2015]菜肴制作
题意:给你一组关系,使得入点必须在出点后做掉。求最小的字典序
比较好想,先建个反图,然后用堆套上拓扑排序,实现从后往前字典序最大
等价于实现了从前往后字典序最小。。。
扩展:一些比较难搞的条件,可以尝试反转,联系类似的算法,对于题目给定的要求要进一步转化。。(需要的话),偏序关系可以往拓扑方向想

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;

int T,n,m,h[MAXN],tot,in[MAXN],rest;

struct node{
	int from,to,next;
}e[MAXN << 1];

void add(int x , int y){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].next = h[x];
	h[x] = tot;
}

void init(){
	memset(in , 0 , sizeof(in));
	memset(h , -1 , sizeof(h));
	cin>>n>>m;int x,y;tot = 0;rest = n;
	for(int i = 1 ; i <= m ; i++){
		cin>>x>>y;
		in[x]++;
		add(y , x);
	}
}
stack<int>ans;
void solve(){
	 priority_queue<int> q;
	for(int i = 1 ; i <= n ; i++){
		if(!in[i])q.push(i);
	}	
	int now;
	while(!q.empty()){
		now = q.top();q.pop();rest--;
		ans.push(now);
		for(int i = h[now] ; i != (-1) ; i = e[i].next){
			in[e[i].to]--;if(!in[e[i].to])q.push(e[i].to);
		}
	}
	if(rest){
		cout<<"Impossible!"<<endl;
		while(!ans.empty())ans.pop();
		return;
	}
	while(!ans.empty()){
		cout<<ans.top()<<" ";
		ans.pop();	
	}
	cout<<endl;
}

int main(){
	cin>>T;
	while(T--){
		init();
		solve();	
		
	}
}

luoguP1282 多米诺骨牌
你先把暴力写出来,发现A与B的值可以做成一个差,就可以少一维

#include<bits/stdc++.h>
#define MAXN 1005
using namespace std;

int n,a[MAXN],b[MAXN],f[1005][12005];
void init(){
	cin>>n;
	for(int i = 1 ; i <= n ; i++)cin>>a[i]>>b[i];
}

void solve(){
	memset(f , 0x3f , sizeof(f));f[0][6000] = 0;
	for(int i = 1 ; i <= n ; i++){
		for(int S = 6000 - i * 6 ; S <= 6000 + i * 6 ; S++){
			f[i][S] = min(f[i - 1][S + (a[i] - b[i])] , f[i - 1][S + (b[i] - a[i])] + 1);
		}
	}
	int ans = 9999999,minl = 9999999;
	for(int i = 0 ; i <= 12000 ; i++){
		if(f[n][i] < 1005 && abs(i - 6000) < ans){
			ans = abs(6000 - i);
			minl = f[n][i];
		}
	}
	cout<<minl<<endl;
}

int main(){
	init();
	solve();
}

luoguP1126 机器人搬重物
纯bfs。。。dfs写会t飞

#include<bits/stdc++.h>
#define MAXN 55
using namespace std;

int n,m,tu[MAXN][MAXN],BX,BY,TX,TY,BR,f[MAXN][MAXN][5];
int dx[4] = {-1 , 0, 1 , 0};
int dy[4] = {0 , -1 , 0 , 1};
struct node{
	int x,y,r;
};
queue<node>q;

int check(int nowx , int nowy){
	if(tu[nowx - 1][nowy - 1] == 1 || tu[nowx - 1][nowy] == 1)return 2;
	if(tu[nowx][nowy - 1] == 1 || tu[nowx][nowy] == 1)return 2;
	return 1;
}


void init(){
	memset(f , 0x3f , sizeof(f));
	cin>>n>>m;
	for(int i = 1 ; i <= n ; i++)for(int j = 1 ; j <= m ; j++)cin>>tu[i][j];
	char R;cin>>BX>>BY>>TX>>TY>>R;
	BX++ , BY++ , TX++ , TY++ , n++ , m++;
	if(R == 'N')BR = 0;
	if(R == 'S')BR = 2;
	if(R == 'W')BR = 1;
	if(R == 'E')BR = 3;
	f[BX][BY][BR] = 0;
	q.push((node){BX , BY , BR});
}

int zzx,zzy;
void bfs(){
	node now;
	while(!q.empty()){
		now = q.front() , q.pop();
		for(int i = 1 ; i <= 3; i++){
			zzx = now.x + dx[now.r] * i;
			zzy = now.y + dy[now.r] * i;
			if(check(zzx , zzy) != 1)break; 
			if(min(zzx , zzy) < 2)break;
			if(zzx >= n || zzy >= m)break;
			if(f[zzx][zzy][now.r] < f[now.x][now.y][now.r] + 1)continue;
			f[zzx][zzy][now.r] = f[now.x][now.y][now.r] + 1;
			q.push((node){zzx , zzy , now.r});
		}
		if(f[now.x][now.y][(now.r + 1) % 4] > f[now.x][now.y][now.r] + 1){
			f[now.x][now.y][(now.r + 1) % 4] = f[now.x][now.y][now.r] + 1;
			q.push((node){now.x , now.y , (now.r + 1) % 4});
		}
		if(f[now.x][now.y][((now.r - 1) % 4 + 4) % 4] > f[now.x][now.y][now.r] + 1){
			f[now.x][now.y][((now.r - 1) % 4 + 4) % 4] = f[now.x][now.y][now.r] + 1;
			q.push((node){now.x , now.y , ((now.r - 1) % 4 + 4) % 4});
		}	
	}
	int ans = 999999;
	for(int i = 0 ; i < 4 ; i++)ans = min(ans , f[TX][TY][i]);
	if(ans == 999999)cout<<-1<<endl;
	else cout<<ans<<endl;
}

int main(){
	init();
	bfs();
}

luoguP1168 中位数
一个比较重要的技巧,用一个对顶堆动态维护中位数,使得这两个堆大小不超过。。
或者拿主席树或者一些奇奇怪怪的数据结构也可以做

#include<bits/stdc++.h>
#define MAXN 100005
typedef long long ll;
using namespace std;

ll n,a[MAXN],zz,zz2;

priority_queue<ll> q;
priority_queue <ll,vector<ll>,greater<ll> > q2;

void init(){
	cin>>n;
	for(int i = 1 ; i <= n ; i++)cin>>a[i];
	q.push(a[1]);
	cout<<a[1]<<endl;
}

void solve(){
	for(int i = 2 ; i <= n ; i++){
		if(q.top() > a[i])q.push(a[i]);
		else q2.push(a[i]);
		zz = q.size() , zz2 = q2.size();
		while(abs(zz - zz2) > 1){
			if(zz > zz2)q2.push(q.top()) , q.pop();
			else q.push(q2.top()) , q2.pop();
			zz = q.size() , zz2 = q2.size();
		}
		if(i % 2 == 1)cout<<(q.size() > q2.size() ? q.top() : q2.top())<<endl;
	}
}

int main(){
	init();
	solve();
}

luoguP5201 [USACO19JAN]Shortcut G
奶牛屑题,考虑先建一颗最小字典序的最短距离生成树
然后直接跑就行了

#include<bits/stdc++.h>
#define MAXN 50005
typedef long long ll;
using namespace std;

ll n,m,T,h[MAXN][2],c[MAXN],tot[2],dis[MAXN],vis[MAXN],sum[MAXN],ans;
queue<ll>q;
struct node{
	ll from,to,cost,next,full;
}e[MAXN << 1][2];

void add(int x , int y , ll z , int k){
	tot[k]++;
	e[tot[k]][k].from = x;
	e[tot[k]][k].to = y;
	e[tot[k]][k].cost = z;
	e[tot[k]][k].next = h[x][k];
	h[x][k] = tot[k];
}

void init(){
	memset(vis , -1 , sizeof(vis));
	memset(dis , 0x3f , sizeof(dis));
	memset(h , -1 , sizeof(h));
	tot[0] = tot[1] = 0;
	cin>>n>>m>>T;ll x,y,z;
	for(int i = 1 ; i <= n ; i++)cin>>c[i];
	for(int i = 1 ; i <= m ; i++){
		cin>>x>>y>>z;
		add(x , y , z , 0);
		add(y , x , z , 0);
	}
}

int dfs(int now , int fa){
	for(int i = h[now][1] ; i != (-1) ; i = e[i][1].next){
		if(e[i][1].to == fa)continue;
		dfs(e[i][1].to , now);
		e[i][1].full = c[e[i][1].to];
		c[now] += c[e[i][1].to];
	}
}

void solve(){
	ll now;
	q.push(1);dis[1] = 0;vis[1] = 1;
	while(!q.empty()){
		now = q.front();vis[now] = (-1);q.pop();
		for(int i = h[now][0] ; i != (-1) ; i = e[i][0].next){
			if(dis[e[i][0].to] > dis[now] + e[i][0].cost){
				dis[e[i][0].to] = dis[now] + e[i][0].cost;
				if(vis[e[i][0].to] == (-1))q.push(e[i][0].to) , vis[e[i][0].to] = 1;
			}
		}
	}
	ll zz;
	for(int i = 2 ; i <= n ; i++){
		zz = 999999;
		for(int j = h[i][0] ; j != (-1) ; j = e[j][0].next){
			if(dis[e[j][0].to] + e[j][0].cost == dis[i]){
				if(zz == 999999)zz = j;
				else if(e[zz][0].to > e[j][0].to)zz = j;
			}
		}
		add(i , e[zz][0].to , e[zz][0].cost , 1);
		add(e[zz][0].to , i , e[zz][0].cost , 1);
	}
	dfs(1 , 1);
	for(int i = 1 ; i <= n ; i++){
		ans = max(ans , (dis[i] - T) * c[i]);
	}
	cout<<ans<<endl;
}

int main(){
	init();
	solve();
}

luoguP5196 [USACO19JAN]Cow Poetry G
先算出长度为n的字符串组成的方案
——>>>得到了以那个字符串结尾的诗句的方案数
——>>>得到了以那个韵部结尾的方案数
然后这题其实就结束了

#include<bits/stdc++.h>
#define MAXN 5005
typedef long long ll;
using namespace std;
ll mod = 1000000007;
ll n,m,k,s[MAXN],c[MAXN],f[100005],num[MAXN],tp[100005],ans,tot,p[MAXN];

ll poww(ll x , ll y){
	ll zz = 1;
	while(y){
		if(y & 1)zz = (zz * x) % mod;
		x = (x * x) % mod;
		y = y >> 1;
	}
	return zz % mod;
}

void init(){
	cin>>n>>m>>k;char zz;f[0] = ans = 1;
	for(int i = 1 ; i <= n ; i++)cin>>s[i]>>c[i];
	for(int i = 1 ; i <= m ; i++)cin>>zz , num[zz - 'A' + 1]++;
}

void solve(){
	for(int i = 1 ; i <= k ; i++)for(int j = 1 ; j <= n ; j++)
	if(i >= s[j])f[i] = (f[i] + f[i - s[j]]) % mod;
	for(int i = 1 ; i <= n ; i++)tp[c[i]] = (tp[c[i]] + f[k - s[i]]) % mod;
	for(int i = 1 ; i <= 26 ; i++){
		if(!num[i])continue;
		++tot;
		for(int j = 1 ; j <= n ; j++){
			if(!tp[j])continue;
			p[tot] = (p[tot] + poww(tp[j] , num[i])) % mod;
		}
	}
	for(int i = 1 ; i <= tot ; i++)ans = (ans * p[i]) % mod;
	cout<<ans<<endl;
}

int main(){
	init();
	solve();
}

luoguP5199 [USACO19JAN]Mountain View S
有个很妙的定理,当前等腰直角三角形到x轴的投影可以决定这个等腰直角三角形的顶点是否被包含

自证不难

#include<bits/stdc++.h>
#define MAXN 100005
typedef long long ll;
using namespace std;

ll n,x,y,ans;

struct node{
	ll l,r;
}t[MAXN];

bool cmp(node a , node b){
	if(a.l == b.l)return a.r > b.r;
	else return a.l < b.l;
}

void init(){
	cin>>n;
	for(int i = 1 ; i <= n ; i++)cin>>x>>y , t[i].l = x - y , t[i].r = x + y;
}

void solve(){
	sort(t + 1 , t + 1 + n , cmp);
	ll now = -99999999999;
	for(int i = 1 ; i <= n ; i++){
		if(t[i].r > now)now = t[i].r , ans++;
	}
	cout<<ans<<endl;
}

int main(){
	init();
	solve();
}

luoguP3390 【模板】矩阵快速幂
看了点线性代数之后,这个东西就比较好理解了
初始话就用 E E E去成,一样的。
但矩阵乘法没交交换律,故要小心写错

#include<bits/stdc++.h>
#define MAXN 105
typedef long long ll;
using namespace std;

ll n,k,mod = 1000000007;

struct node{
	ll a[105][105]; 
}A,B;


node operator * (node x , node y){
	node z;
	for(int i = 1 ; i <= n ; i++)for(int j = 1 ; j <= n ; j++)z.a[i][j] = 0;
	for(int i = 1 ; i <= n ; i++){
		for(int j = 1 ; j <= n ; j++){
			for(int k = 1 ; k <= n ; k++){
				z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j]) % mod;	
			}
		}
	}
	return z;
}

int main(){
	cin>>n>>k;
	for(int i = 1 ; i <= n ; i++)for(int j = 1 ; j <= n ; j++)cin>>A.a[i][j];
	for(int i = 1 ; i <= n ; i++)B.a[i][i] = 1;
	while(k){
		if(k & 1)B = B * A;
		A = A * A;
		k = k >> 1;
	}
	for(int i = 1 ; i <= n ; i++){
		for(int j = 1 ; j <= n ; j++){
			cout<<B.a[i][j]<<" ";	
		}	
		cout<<endl;
	}
}

luoguP3806 【模板】点分治1
嘛,这个东西就是一个假的暴力,,,
总划分重心的复杂度是 O ( n l o g n ) O(nlogn) O(nlogn)
一般这上面的操作有两种
1.不用桶的,那种值域很大的
2.用桶的,值域很小
注意,这个东西,我只会处理那种跟路径有关的问题。。
跟子树一些特征之类的还没遇到过

#include<bits/stdc++.h>
#define MAXN 80005
typedef long long ll;
using namespace std;

int n,m,k,h[MAXN],tot,vis[MAXN],sz[MAXN],zhong[MAXN],maxl,ask[MAXN],ans[MAXN];
int dis[MAXN],js,dui[MAXN],in[40000005],jjs;

struct node{
	int from,to,nex,cost;
}e[MAXN << 1];

void add(int x , int y , int z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z;
	e[tot].nex = h[x];
	h[x] = tot;
	return;
}

void getsz(int now , int fa){
	sz[now] = 1;
	for(int i = h[now] ; i != (-1) ; i = e[i].nex){
		if(e[i].to == fa || vis[e[i].to])continue;
		getsz(e[i].to , now);
		sz[now] += sz[e[i].to];
	}
	return;
}

void getzx(int now , int fa , int yl){
	zhong[now] = 0;
	for(int i = h[now] ; i != (-1) ; i = e[i].nex){
		if(e[i].to == fa || vis[e[i].to])continue;
		getzx(e[i].to , now , yl);
		if(sz[zhong[now]] < sz[e[i].to])zhong[now] = e[i].to;
	}
	zhong[now] = max(sz[zhong[now]] , sz[yl] - sz[zhong[now]]);
	if(zhong[now] < zhong[maxl])maxl = now;
	return;
}

void getdis(int now , int fa){
	for(int i = h[now] ; i != (-1) ; i = e[i].nex){
		if(e[i].to == fa || vis[e[i].to])continue;
		dis[e[i].to] = dis[now] + e[i].cost;
		getdis(e[i].to , now);
	}
	dui[++js] = dis[now];
	return;
}

void calc(int now){
	js = 0;
	for(int i = h[now] ; i != (-1) ; i = e[i].nex){
		if(vis[e[i].to])continue;
		dis[e[i].to] = e[i].cost , jjs = js;
		dui[++js] = dis[e[i].to];
		getdis(e[i].to , now);
		
		for(int i = 1 ; i <= m ; i++){
			for(int j = jjs + 1 ; j <= js ; j++){
				if(ask[i] < dui[j])continue;
				if(in[ask[i] - dui[j]])ans[i] = 1;
			}
		}
		for(int i = jjs ; i <= js ; i++)if(dui[i] <= 10000005)in[dui[i]] = 1;
	}
	for(int i = 1 ; i <= js ; i++)in[dui[i]] = 0;
	return;
}

void solve(int now){
	vis[now] = 1;
	calc(now);getsz(now , now);
	for(int i = h[maxl] ; i != (-1) ; i = e[i].nex){
		if(vis[e[i].to])continue;
		maxl = 0;getzx(e[i].to , now , e[i].to);
		solve(maxl);
	}
	return;
}

void init(){
	memset(ans , -1 , sizeof(ans));
	memset(in, 0 , sizeof(in));
	memset(h , -1 , sizeof(h));
	cin>>n>>m;
	int x,y,z;tot = 0 , sz[n + 1] = n;
	zhong[0] = 9999999;in[0] = 1;
	for(int i = 1 ; i < n ; i++){
		cin>>x>>y>>z;
		add(x , y , z);
		add(y , x , z);
	}
	for(int i = 1 ; i <= m ; i++)cin>>ask[i];
	maxl = 0;getzx(1 , 1 , n + 1);
	solve(maxl);
	for(int i = 1 ; i <= m ; i++){
		if(ans[i] == 1)cout<<"AYE"<<endl;
		else cout<<"NAY"<<endl;
	}
}



int main(){
	init();
}

luoguP4178 Tree
点分治的屑题
不过要注意,如果在分治过程中直接算会t飞,要开个桶

#include<bits/stdc++.h>
#define MAXN 80005
using namespace std;

int n,K,h[MAXN],tot,sz[MAXN],maxl[MAXN],dis[MAXN],vis[MAXN],ZX;
int dui[MAXN],js,jjs,ans[20005],sum,zzq[20005];

struct node{
	int from , to , cost , next;
}e[MAXN << 1];

void add(int x , int y , int z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z;
	e[tot].next = h[x];
	h[x] = tot;
}

void getsz(int now , int fa){
	sz[now] = 1;maxl[now] = 0;
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(e[i].to == fa || vis[e[i].to])continue;
		getsz(e[i].to , now);
		sz[now] += sz[e[i].to];
		if(sz[e[i].to] > sz[maxl[now]])maxl[now] = e[i].to;
	}
}

void getzx(int now , int fa , int yl){
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(e[i].to == fa || vis[e[i].to])continue;
		getzx(e[i].to , now , yl);
	}
	maxl[now] = max(sz[maxl[now]] , sz[yl] - sz[maxl[now]]);
	if(maxl[now] <= maxl[ZX])ZX = now;
}

void getdis(int now , int fa){
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(e[i].to == fa || vis[e[i].to])continue;
		dis[e[i].to] = dis[now] + e[i].cost;
		getdis(e[i].to , now);
	}
	if(dis[now] <= K)dui[++js] = dis[now];
}

void calc(int now){
	js = 0;
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(vis[e[i].to])continue;
		jjs = js;dis[e[i].to] = e[i].cost;
		getdis(e[i].to , now);
		for(int j = 1 ; j <= K ; j++){
			if(!zzq[j])continue;
			for(int k = jjs + 1 ; k <= js ; k++){
				if(j + dui[k]> K)continue;	
				ans[dui[k] + j] += zzq[j];
			}
		}
		for(int j = jjs + 1 ; j <= js ; j++)zzq[dui[j]]++;
	}
	for(int i = 1 ; i <= js ; i++)zzq[dui[i]]--;
	for(int i = 1 ; i <= js ; i++){
		if(dui[i] > K)continue;
		ans[dui[i]]++;	
	}
}

void solve(int now){
	getsz(now , now);calc(now);vis[now] = 1;
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(vis[e[i].to])continue;
		ZX = 0;getzx(e[i].to , now , e[i].to);
		solve(ZX);
	}
}

void init(){
	memset(h , -1 , sizeof(h));
	cin>>n;int u,v,w;maxl[0] = 9999999;
	for(int i = 1 ; i < n ; i++)cin>>u>>v>>w , add(u , v , w) , add(v , u , w);
	cin>>K;
	getsz(1 , 1);ZX = 0;
	getzx(1 , 1 , 1);
	solve(ZX);
	for(int i = 1 ; i <= K ; i++)sum = sum + ans[i];
	cout<<sum<<endl;
}

int main(){
	init();
	
}

luoguP2634 [国家集训队]聪聪可可
这个类似与上面

#include<bits/stdc++.h>
#define MAXN 50005
using namespace std;

int n,h[MAXN],tot,dis[MAXN],sz[MAXN],maxl[MAXN],ZX,vis[MAXN],a1,a2;
int dui[MAXN],js,jjs,tp[4],ans[4];

struct node{
	int from,to,cost,next;
}e[MAXN << 1];

void add(int x , int y , int z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z % 3;
	e[tot].next = h[x];
	h[x] = tot;
}

void getsz(int now , int fa){
	sz[now] = 1 , maxl[now] = 0;
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(e[i].to == fa || vis[e[i].to])continue;
		getsz(e[i].to , now);
		sz[now] += sz[e[i].to];
		if(sz[e[i].to] > sz[maxl[now]])maxl[now] = e[i].to;
	}
}

void getzx(int now , int fa , int yl){
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(e[i].to == fa || vis[e[i].to])continue;
		getzx(e[i].to , now , yl);
	}
	maxl[now] = max(sz[maxl[now]] , sz[yl] - sz[maxl[now]]);
	if(maxl[now] < maxl[ZX])ZX = now;
}

void getdis(int now , int fa){
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(e[i].to == fa || vis[e[i].to])continue;
		dis[e[i].to] = (dis[now] + e[i].cost) % 3;
		getdis(e[i].to , now);
	}
	js++;
	dui[js] = dis[now] % 3;
}

void calc(int now){
	js = 0;
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(vis[e[i].to])continue;
		dis[e[i].to] = e[i].cost , jjs = js;
		getdis(e[i].to , now);
		for(int j = jjs + 1 ; j <= js ; j++)for(int k = 0 ; k <= 2 ; k++)ans[(k + dui[j]) % 3] += tp[k];
		for(int j = jjs + 1 ; j <= js ; j++)tp[dui[j] % 3]++;
	}
	for(int i = 0 ; i <= 2 ; i++)ans[i] += tp[i];
	memset(tp , 0 , sizeof(tp));
}

void solve(int now){
	calc(now);vis[now] = 1;getsz(now , now);
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		if(vis[e[i].to])continue;
		ZX = 0;getzx(e[i].to , now , e[i].to);
		solve(ZX);
	}
}

void init(){
	tot = 0;
	memset(h , -1 , sizeof(h));
	cin>>n;int x,y,w;maxl[0] = 99999999;
	for(int i = 1 ; i < n ; i++){
		cin>>x>>y>>w;
		add(x , y , w);
		add(y , x , w);
	}
	getsz(1 , 1) , ZX = 0 , getzx(1 , 1 , 1);
	solve(ZX);
	ans[0] = ans[0] * 2 + n;
	a1 = ans[0] , a2 = n * n;
	for(int i = 2 ; i <= min(a1 , a2) ; i++){
		while(a1 % i == 0 && a2 % i == 0){
			a1 /= i;
			a2 /= i;
		}
	}
	cout<<a1<<"/"<<a2<<endl;
}

int main(){
	init();
}

luoguP3371 【模板】单源最短路径(弱化版)
模板题

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

ll n,m,s,h[30005],tot,vis[30005],dis[30005],op = 1;

struct node{
	ll from,to,cost,next;
}e[600005 << 1];

struct node2{
	ll num,val;
};
priority_queue<node2>q;
bool operator < (node2 x , node2 y){
	return x.val > y.val;
}

void add(ll x , ll y , ll z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z;
	e[tot].next = h[x];
	h[x] = tot;
}

void disjkra(ll beg){
	memset(vis , -1 , sizeof(vis));
	dis[beg] = 0;q.push((node2){beg , 0});
	node2 now;
	while(!q.empty()){
		now = q.top();q.pop();
		if(vis[now.num] == 1)continue;
		vis[now.num] = 1;
		for(int i = h[now.num] ; i != (-1) ; i = e[i].next){
			if(dis[e[i].to] > dis[now.num] + e[i].cost){
				dis[e[i].to] = dis[now.num] + e[i].cost;
				if(vis[e[i].to] == (-1))q.push((node2){e[i].to , dis[e[i].to]});
			}
		}
	}
}

void init(){
	tot = 0;memset(h , -1 , sizeof(h));
	cin>>n>>m>>s;int x,y,z;
	for(int i = 1 ; i <= 31 ; i++)op = op << 1;
	op--;
	for(int i = 1 ; i <= n ; i++)dis[i] = op;
	for(int i = 1 ; i <= m ; i++){
		cin>>x>>y>>z;
		add(x , y , z);
	}
	disjkra(s);
	for(int i = 1 ; i <= n ; i++){
		cout<<dis[i]<<" ";
	}
}

int main(){
	init();
}

luoguP3385 【模板】负环
有两种判别方法
1.收缩次数大于n
2.距离起点距离大于n

#include<bits/stdc++.h>
#define MAXN 30005
typedef long long ll;
using namespace std;

int T,n,m,h[MAXN],tot,dis[MAXN],vis[MAXN],cnt[MAXN];

struct node{
	int from,to,cost,next;
}e[MAXN << 1];

queue<int>q;

void add(int x , int y , int z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z;
	e[tot].next = h[x];
	h[x] = tot;
}

int spfa(int beg){
	memset(cnt , 0 , sizeof(cnt));
	memset(dis , 0x3f , sizeof(dis));
	memset(vis , 0 , sizeof(vis));
	queue<int>q;q.push(beg);vis[beg] = 1;dis[beg] = 0;cnt[beg] = 1;
	int now;
	while(!q.empty()){
		now = q.front();q.pop();vis[now] = 0;
		for(int i = h[now] ; i != (-1) ; i = e[i].next){
			if(dis[e[i].to] > dis[now] + e[i].cost){
				dis[e[i].to] = dis[now] + e[i].cost;
				cnt[e[i].to] = cnt[now] + 1;
				if(cnt[e[i].to] > n)return 2;
				if(!vis[e[i].to])vis[e[i].to] = 1 , q.push(e[i].to);
			}
		}
	}
	return 1;
}

void init(){
	memset(h , -1 , sizeof(h));tot = 0;
	cin>>n>>m;int x , y , z;
	for(int i = 1 ; i <= m ; i++){
		cin>>x>>y>>z;
		add(x , y , z);
		if(z >= 0)add(y , x , z);
	}
	if(spfa(1) == 2)cout<<"YES"<<endl;
	else cout<<"NO"<<endl;	
}

int main(){
	cin>>T;
	while(T--){
		init();	
	}
}
#include<bits/stdc++.h>
#define MAXN 30005
typedef long long ll;
using namespace std;

int T,n,m,h[MAXN],tot,dis[MAXN],vis[MAXN],in[MAXN];

struct node{
	int from,to,cost,next;
}e[MAXN << 1];

queue<int>q;

void add(int x , int y , int z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z;
	e[tot].next = h[x];
	h[x] = tot;
}

int spfa(int beg){
	memset(in , 0 , sizeof(in));
	memset(dis , 0x3f , sizeof(dis));
	memset(vis , 0 , sizeof(vis));
	queue<int>q;q.push(beg);vis[beg] = 1;dis[beg] = 0;
	int now;
	while(!q.empty()){
		now = q.front();q.pop();vis[now] = 0;
		for(int i = h[now] ; i != (-1) ; i = e[i].next){
			if(dis[e[i].to] > dis[now] + e[i].cost){
				dis[e[i].to] = dis[now] + e[i].cost;
				in[e[i].to]++;
				if(in[e[i].to] > n)return 2;
				if(!vis[e[i].to])vis[e[i].to] = 1 , q.push(e[i].to);
			}
		}
	}
	return 1;
}

void init(){
	memset(h , -1 , sizeof(h));tot = 0;
	cin>>n>>m;int x , y , z;
	for(int i = 1 ; i <= m ; i++){
		cin>>x>>y>>z;
		add(x , y , z);
		if(z >= 0)add(y , x , z);
	}
	if(spfa(1) == 2)cout<<"YES"<<endl;
	else cout<<"NO"<<endl;	
}

int main(){
	cin>>T;
	while(T--){
		init();	
	}
}

luoguP1257 平面上的最接近点对
O ( n 2 ) O(n^2) O(n2)枚举即可

#include<bits/stdc++.h>
#define MAXN 10005
using namespace std;

int n;
double ans = 99999999;
struct node{
	double x,y;
}t[MAXN];

int main(){
	cin>>n;
	for(int i = 1 ; i <= n ; i++)cin>>t[i].x>>t[i].y;
	for(int i = 1 ; i <= n ; i++){
		for(int j = i + 1 ; j <= n ; j++){
			ans = min(ans , sqrt((t[i].x - t[j].x) * (t[i].x - t[j].x) + (t[i].y - t[j].y) * (t[i].y - t[j].y)));
		}
	}
	printf("%.4f\n" , ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值