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<<'\n';

}

 我觉得我这个可能有锅

贴一下标程

标程是跑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<<'\n';
    }
}

贴一下前向星代码

#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\n",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<<'\n';
    }
}

 

posted @ 2019-07-28 00:03  liulex  阅读(216)  评论(0)    收藏  举报