zoukankan      html  css  js  c++  java
  • free

    free

    终于会这题了QAQ

    有些边可以变为0,得用dp做,亏我还妄想贪心来着

    写个dijk也能出锅---

    dp[i][j] i到起点把其中j条边变为0的最小代价==

    ​#include<bits/stdc++.h>
    using namespace std;
    int n,m,S,T,K;
    int A[3003][3005];
    #define INF 100000099
    int dp[3003][3005];
    #define P pair<int,int>
    priority_queue<P,vector<P>,greater<P> >pq;
    void dijk()
    {
        for(int i=1; i<=n; i++)
        {
    
            for(int j=0; j<=K; j++)
            {
                dp[i][j]=INF;
                if(i==S)dp[i][j]=0;
            }
            //cout<<i<<" "<<dp[S][0]<<endl;
            
            //if(i==0)cout<<dp[S][i]<<endl;
        }
        //cout<<dp[S][1]<<endl;
        pq.push(P(0,S));
        while(!pq.empty())
        {
            P a=pq.top();
            pq.pop();
            int x=a.first;
            int y=a.second;
            //if(y==T)
            // cout<<y<<endl;
            if(dp[y][0]<x)continue;
            // dp[y][0]=x;///???
            // cout<<y<<" "<<dp[y][0]<<endl;
            for(int i=1; i<=n; i++)
            {
                //cout<<dp[i][0]<<" "<<dp[y][0]<<" "<<A[y][i]<<" NM"<<i<<endl;
                //cout<<(A[y][i]!=0)<<(A[y][i]!=INF)<<(dp[i][0]<dp[y][0]+A[y][i])<<endl;
                if((A[y][i]!=0)&&(A[y][i]!=INF)&&(dp[i][0]>dp[y][0]+A[y][i]))
                {
                    // cout<<i<<"???"<<endl;
                    dp[i][0]=min(dp[i][0],dp[y][0]+A[y][i]);
                    for(int j=1; j<=K; j++)
                        dp[i][j]=min(dp[i][j],min(dp[y][j]+A[i][j],dp[y][j-1]));
                    //cout<<"TRE"<<endl;
                    pq.push(P(dp[i][0],i));
                }
            }
        }
    
    }
    int main()
    {
        scanf("%d%d%d%d%d",&n,&m,&S,&T,&K);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(i!=j)A[i][j]=INF;
            }
        }
        int a,b,c;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            A[a][b]=A[b][a]=c;
        }
        int ans=INF;
        dijk();
        for(int i=0; i<=K; i++)
        {
            ans=min(ans,dp[T][i]);
            // cout<<dp[T][i]<<endl;
        }
       
        cout<<ans<<'
    ';
    
    }

     我觉得我这个可能有锅

    贴一下标程

    标程是跑k+1次dijk

    每次更新一下dis数组

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef unsigned int u32;
    typedef pair<int,int> pii;
    template <typename T> void chmin(T &x,const T &y)
    {
        if(x>y)x=y;
    }
    #define rep(i,l,r) for(int i=l;i<=r;++i)
    #define per(i,r,l) for(int i=r;i>=l;--i)
    const int N=1000+5;
    vector<pii>lk[N];
    int n,dp[N],dp0[N];
    
    void upd()
    {
        priority_queue<pii>heap;
        rep(i,1,n)heap.push({-dp[i],i});
        while(!heap.empty())
        {
            pii p=heap.top();
            heap.pop();
            int x=p.second;
            if(-p.first!=dp[x])continue;
            for(auto e:lk[x])
            {
                int y=e.first;
                if(dp[y]>dp[x]+e.second)
                    heap.push({-(dp[y]=dp[x]+e.second),y});
            }
        }
    }
    
    int main()
    {
        //freopen("1.in","r",stdin);//freopen("tmp","w",stdout);
        int m,S,T,k;
        cin>>n>>m>>S>>T>>k;
        rep(i,1,m)
        {
            int x,y,l;
            scanf("%d%d%d",&x,&y,&l);
            lk[x].push_back({y,l});
            lk[y].push_back({x,l});
        }
        rep(i,1,n)dp[i]=1e9;
        dp[S]=0;
        upd();
        rep(tmp,1,k)///1-k
        {
            rep(i,1,n)dp0[i]=dp[i];
            rep(x,1,n)
            for(auto e:lk[x])chmin(dp[e.first],dp0[x]);///更新距离
            upd();
        }
        cout<<dp[T];
    }

    Magical Girl Haze

    南昌网络赛的一道题,用上面的方式转移一直过不了,找不到hack数据===

    #include<bits/stdc++.h>
    using namespace std;
    int T;
    typedef long long ll;
    #define P pair<ll,ll> 
    struct Node{
        ll id,sta,
        w;
        Node(ll id,ll sta,ll w):id(id),sta(sta),w(w){}
        bool operator<(const Node &a)const{
            return w>a.w;
        }
        //Node(ll id,ll w):id(id),w(w){}
    
    };
    ll dp[100005][11];
    bool vis[100005][11];
    #define INF 1e18+7
    vector<P> G[100005];
    priority_queue<Node > q;
    int N,M,K;
    void init()
    {
        for(int i=1;i<=N;i++){
            G[i].clear();
        }
      
        for(int i=1;i<=N+2;i++){
            for(int j=0;j<=K;j++){
                dp[i][j]=INF;
                vis[i][j]=0;
                if(i==1){
                    dp[i][j]=0;
                }
            }
            
        }
    }
    void dijk()
    {
        q.push(Node(1,0,0));
         // memset(vis,0,sizeof(vis));
        while(!q.empty()){
           Node t=q.top();q.pop();
           ll u=t.id;
           vis[u][t.sta]=1;
           if(dp[u][t.sta]<t.w)continue;
            int _n=G[u].size();
           for(int i=0;i<_n;i++){
               ll v=G[u][i].first;
               ll w=G[u][i].second;
               if(vis[v][t.sta])continue;
               if(t.sta<K&&dp[v][t.sta+1]>t.w){
                    dp[v][t.sta+1]=t.w;
                    q.push(Node(v,t.sta+1,t.w));
                }
               if(dp[v][t.sta]-dp[u][t.sta]>w){
                    dp[v][t.sta]=dp[u][t.sta]+w;
                    q.push(Node(v,t.sta,dp[v][t.sta]));
                }
           }
            
            //memset(dis,125,sizeof(dis));
      
            /*P a=q.top();
            q.pop();
            ll x=a.first;
            ll y=a.second;
            if(dp[y][0]<x)continue;
            ll n=G[y].size();
            for(int i=0;i<n;i++){
                ll xx=G[y][i].first;
                ll yy=G[y][i].second;
                if(dp[xx][0]>=x+yy){
                    dp[xx][0]=min(dp[xx][0],x+yy);
                    for(int j=1;j<=K;j++){
                        dp[xx][j]=min(min(dp[xx][j],min(dp[y][j]+yy,dp[y][j-1])),dp[xx][j-1]);
                    }
                    q.push(P(dp[xx][0],xx));
                }
            }*/
        }
        
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d",&N,&M,&K);
            init();
            ll a,b; ll c;
            for(int i=0;i<M;i++){
                scanf("%lld%lld%lld",&a,&b,&c);
                G[a].push_back(P(b,c));
            }
            dijk();
            ll ans=INF;
            for(int i=0;i<=K;i++){
                ans=min(ans,dp[N][i]);
            }
            cout<<ans<<'
    ';
        }
    }

    贴一下前向星代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=5e5+7;
    ll n,m,k;
    struct Edge{
        ll v,w,nxt;
        Edge(ll v=0,ll w=0,ll nxt=0):v(v),w(w),nxt(nxt){}
    }e[N];
    ll edn,p[N];
    void add(ll u,ll v,ll w){
        e[++edn]=Edge(v,w,p[u]);p[u]=edn;
    }
    struct Node{
        ll id,sta,w;
        Node(ll id,ll sta,ll w):id(id),sta(sta),w(w){}
        bool operator<(const Node &a)const{
            return w>a.w;
        }
    };
    ll vis[N][20],dis[N][20];
    void dij(){
        priority_queue<Node>q;
        memset(dis,125,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[1][0]=0;
        q.push(Node(1,0,0));
        while(!q.empty()){
            Node t=q.top();q.pop();
            ll u=t.id;
            vis[u][t.sta]=1;
            for(ll i=p[u];~i;i=e[i].nxt){
                ll v=e[i].v;
                if(vis[v][t.sta]) continue;
                if(t.sta<k&&dis[v][t.sta+1]>t.w){
                    dis[v][t.sta+1]=t.w;
                    q.push(Node(v,t.sta+1,t.w));
                }
                if(dis[v][t.sta]-dis[u][t.sta]>e[i].w){
                    dis[v][t.sta]=dis[u][t.sta]+e[i].w;
                    q.push(Node(v,t.sta,dis[v][t.sta]));
                }
            }
        }
    }
    int main()
    {
        ll t;
        scanf("%lld",&t);
        while(t--){
            scanf("%lld%lld%lld",&n,&m,&k);
            memset(p,-1,sizeof(p));edn=-1;
            ll u,v,w;
            for(ll i=1;i<=m;i++){
                scanf("%lld%lld%lld",&u,&v,&w);
                add(u,v,w);
            }
            dij();
            printf("%lld
    ",dis[n][k]);
        }
        return 0;
    }

    改用上面标程代码

    #include<bits/stdc++.h>
    using namespace std;
    int T;
    typedef long long ll;
    #define P pair<ll,ll> 
    ll dp[100005][11];
    bool vis[100005][11];
    #define INF 1e18+7
    vector<P> G[100005];
    priority_queue<P,vector<P>,greater<P> > q;
    int N,M,K;
    void init()
    {
        for(int i=1;i<=N;i++){
            G[i].clear();
        }
      
        for(int i=1;i<=N+2;i++){
            for(int j=0;j<=1;j++){
                dp[i][j]=INF;
                vis[i][j]=0;
            }
            
        }
    }
    void dijk()
    {
        //q.push(Node(1,0,0));
        //q.push(P(0,1));
       for(int i=1;i<=N;i++)q.push(P(dp[i][0],i));///tips注意每个元素都得先入队
        
        //段错误???
         // memset(vis,0,sizeof(vis));
        while(!q.empty()){
           /*Node t=q.top();q.pop();
           ll u=t.id;
           vis[u][t.sta]=1;
           if(dp[u][t.sta]<t.w)continue;
            int _n=G[u].size();
           for(int i=0;i<_n;i++){
               ll v=G[u][i].first;
               ll w=G[u][i].second;
               if(vis[v][t.sta])continue;
               if(t.sta<K&&dp[v][t.sta+1]>t.w){
                    dp[v][t.sta+1]=t.w;
                    q.push(Node(v,t.sta+1,t.w));
                }
               if(dp[v][t.sta]-dp[u][t.sta]>w){
                    dp[v][t.sta]=dp[u][t.sta]+w;
                    q.push(Node(v,t.sta,dp[v][t.sta]));
                }
           }*/
            
            //memset(dis,125,sizeof(dis));
      
            P a=q.top();
            q.pop();
            ll x=a.first;
            ll y=a.second;
            if(dp[y][0]<x)continue;
            ll n=G[y].size();
            for(int i=0;i<n;i++){
                ll xx=G[y][i].first;
                ll yy=G[y][i].second;
                if(dp[xx][0]>=x+yy){
                    dp[xx][0]=x+yy;
                    q.push(P(dp[xx][0],xx));
                }
            }
        }
        
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d",&N,&M,&K);
            init();
            ll a,b; ll c;
            for(int i=0;i<M;i++){
                scanf("%lld%lld%lld",&a,&b,&c);
                G[a].push_back(P(b,c));
            }
            dp[1][0]=0;
            dp[1][1]=0;
            dijk();
            
            for(int tem=1;tem<=K;tem++)///1-k
            {
            for(int i=1;i<=N;i++)dp[i][1]=dp[i][0];
            for(int x=1;x<=N;x++)
            for(auto e:G[x])if(dp[e.first][0]>dp[x][1])dp[e.first][0]=dp[x][1];///更新距离
            dijk();
           
            }
           ll ans=dp[N][0];
            cout<<ans<<'
    ';
        }
    }
  • 相关阅读:
    实现自动更新文件
    IP零碎知识总结
    有关数据库操作的一些函数
    AppConfig有关零碎知识
    将文件上传到数据库 和 从数据库下载文件到本地
    如何学习编程
    像素、英寸、厘米之间的换算关系
    局域网
    JSP基础知识
    Exchange a,b without using other variables
  • 原文地址:https://www.cnblogs.com/liulex/p/11257377.html
Copyright © 2011-2022 走看看