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);
}