20231009刷题记录

  • P1807 最长路

    直接用 SPFA 求最长路即可,只需把松弛操作的 > 改成 <

    注意 Dijkstra 求最长路不能只改变松弛操作,较麻烦。

    注意数组赋值尽量不用 memset,SPFA 建边要建单向边,否则会出现环。

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    
    const int maxn=1505,maxm=5e4+5;
    int head[maxn],dis[maxn],cnt,n;
    struct edge{int to,nxt,w;}e[maxm];
    bool vis[maxn];
    
    void add(int x,int y,int z){e[++cnt]=(edge){y,head[x],z},head[x]=cnt;}
    
    void spfa()
    {
        for(int i=1;i<=n;i++) dis[i]=-1e9;
        queue<int> q;
        dis[1]=0,q.push(1),vis[1]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            vis[u]=0;
            for(int i=head[u];i;i=e[i].nxt)
                if(dis[e[i].to]<dis[u]+e[i].w)
                {
                    dis[e[i].to]=dis[u]+e[i].w;
                    if(!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
                }
        }
    }
    
    signed main()
    {
        int m;cin>>n>>m;
        for(int i=1,u,v,w;i<=m;i++) cin>>u>>v>>w,add(u,v,w);
        spfa();
        cout<<(dis[n]==-1e9?-1:dis[n]);
        return 0;
    }
    
  • P1452 【模板】旋转卡壳

    人类智慧。

    考虑将每一个点的坐标随机旋转之后排序,将前面的点和后面的点进行计算距离 max ⁡ \max max 操作。由于随机旋转操作,会让坐标分布均匀,很难被卡。

    注意是把排序之后前面的点和后面的点比较。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=50005;
    struct node{int x,y,xn,yn;}p[maxn];
    
    bool cmp(node a,node b)
    {
    	if(a.xn!=b.xn) return a.xn<b.xn;
    	return a.yn<b.yn;
    }
    
    int main()
    {
    	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 
    	int n;cin>>n;
    	for(int i=1;i<=n;++i) cin>>p[i].x>>p[i].y,p[i].xn=p[i].x*cos(1.5)-p[i].y*sin(1.5),p[i].yn=p[i].x*sin(1.5)+p[i].y*cos(1.5);
    	sort(p+1,p+n+1,cmp);
    	int ans=0;
    	for(int i=1;i<=min(20000,n);++i)
    		for(int j=n-min(20000,n)+1;j<=n;++j) ans=max(ans,(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
    	cout<<ans;
    	return 0;
    }
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值