2 条题解

  • 1
    @ 2025-9-6 17:53:05

    這道題也不難,我們首先發現如果我們在一個環裡面一直跑並且賺的錢不少於花的錢那麼一定賺的錢為無窮大 如果不能的話我們就可以跑一個spfa來記錄我們到每一個點賺的錢的最大值,如果發現正環就輸出 1-1

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define int long long
    using namespace std;
    bool Test_MLE_start;
    constexpr int N=1005;
    int _=1,l,m,n,k,s,tot=0,head[N],dis[N],cnt[N];bool vis[N];
    struct edge{int v,w,nxt;}a[N<<1];queue<int> q;
    inline int reads(){
    	char c=getchar();
    	int sum=0,f=1;
    	while(!isdigit(c)){
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(isdigit(c)){
    		sum=(sum<<3)+(sum<<1)+(c^'0');
    		c=getchar();
    	}
    	return sum*f;
    }
    inline void files(){
    	freopen("B.in","r",stdin);
    //	freopen("std.out","w",stdout);
    }
    inline void clr(){
    //	Don't forget!
    
    }
    void add(int u,int v,int w){
    	a[++tot].v=v;a[tot].w=w;
    	a[tot].nxt=head[u];
    	head[u]=tot;
    }
    void spfa(int st){
    	memset(dis,-0x3f,sizeof(dis));
    	q.push(st);dis[st]=0,vis[st]=1;
    	while(!q.empty()){
    		int u=q.front();q.pop();vis[u]=0;
    		for(int i=head[u];i;i=a[i].nxt){
    			int v=a[i].v;
    			if(dis[v]<dis[u]+l-a[i].w){
    				dis[v]=dis[u]+l-a[i].w;
    				if(!vis[v]){
    					q.push(v);vis[v]=1,cnt[v]++;
    					if(cnt[v]>n){
    						puts("-1");
    						exit(0);
    					}
    				}
    			}
    		}
    	}
    }
    bool Test_MLE_end;
    signed main(){
    //	printf("%lf Mb\n",(&Test_MLE_end-&Test_MLE_start-1)/1024.0/1024.0);
    //	files();
    //	_=reads();
    	while(_--){
    		clr();l=reads(),m=reads(),n=reads(),k=reads(),s=reads();
    		for(int i=1;i<=m;i++){
    			int u,v;u=reads(),v=reads();
    			add(u,v,0);
    		}for(int i=1;i<=k;i++){
    			int u,v,w;u=reads(),v=reads(),w=reads();
    			add(u,v,w);
    		}spfa(s);int ans=-2e9;
    		for(int i=1;i<=n;i++) ans=max(ans,dis[i]+l);
    		printf("%lld\n",ans);
    	}
    	return 0;
    }
    
    
    • -1
      @ 2025-9-6 17:53:24

      This question is not difficult either. First of all, we found that if we keep running in a loop and earn no less than the money we spend, then the money we earn must be infinite

      If not, we can run an spfa to record the maximum amount of money we earn at each point. If we find a positive loop, we can output 1-1

      #include<iostream>
      #include<cstring>
      #include<cstdio>
      #include<queue>
      #define int long long
      using namespace std;
      bool Test_MLE_start;
      constexpr int N=1005;
      int _=1,l,m,n,k,s,tot=0,head[N],dis[N],cnt[N];bool vis[N];
      struct edge{int v,w,nxt;}a[N<<1];queue<int> q;
      inline int reads(){
      	char c=getchar();
      	int sum=0,f=1;
      	while(!isdigit(c)){
      		if(c=='-') f=-1;
      		c=getchar();
      	}
      	while(isdigit(c)){
      		sum=(sum<<3)+(sum<<1)+(c^'0');
      		c=getchar();
      	}
      	return sum*f;
      }
      inline void files(){
      	freopen("B.in","r",stdin);
      //	freopen("std.out","w",stdout);
      }
      inline void clr(){
      //	Don't forget!
      
      }
      void add(int u,int v,int w){
      	a[++tot].v=v;a[tot].w=w;
      	a[tot].nxt=head[u];
      	head[u]=tot;
      }
      void spfa(int st){
      	memset(dis,-0x3f,sizeof(dis));
      	q.push(st);dis[st]=0,vis[st]=1;
      	while(!q.empty()){
      		int u=q.front();q.pop();vis[u]=0;
      		for(int i=head[u];i;i=a[i].nxt){
      			int v=a[i].v;
      			if(dis[v]<dis[u]+l-a[i].w){
      				dis[v]=dis[u]+l-a[i].w;
      				if(!vis[v]){
      					q.push(v);vis[v]=1,cnt[v]++;
      					if(cnt[v]>n){
      						puts("-1");
      						exit(0);
      					}
      				}
      			}
      		}
      	}
      }
      bool Test_MLE_end;
      signed main(){
      //	printf("%lf Mb\n",(&Test_MLE_end-&Test_MLE_start-1)/1024.0/1024.0);
      //	files();
      //	_=reads();
      	while(_--){
      		clr();l=reads(),m=reads(),n=reads(),k=reads(),s=reads();
      		for(int i=1;i<=m;i++){
      			int u,v;u=reads(),v=reads();
      			add(u,v,0);
      		}for(int i=1;i<=k;i++){
      			int u,v,w;u=reads(),v=reads(),w=reads();
      			add(u,v,w);
      		}spfa(s);int ans=-2e9;
      		for(int i=1;i<=n;i++) ans=max(ans,dis[i]+l);
      		printf("%lld\n",ans);
      	}
      	return 0;
      }
      
      
      • 1

      信息

      ID
      381
      时间
      1000ms
      内存
      256MiB
      难度
      5
      标签
      (无)
      递交数
      36
      已通过
      16
      上传者