P2294 [HNOI2005]狡猾的商人
生活随笔
收集整理的這篇文章主要介紹了
P2294 [HNOI2005]狡猾的商人
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
P2294 [HNOI2005]狡猾的商人
題意:
你需要調查某個商人的賬本,給你n個月內,m條賬單信息,每條賬單信息為x到y月的收入或者支出多少錢,問你根據賬單信息判斷這個賬本是否合理
5 3 1 5 100 3 5 50 1 2 51比如樣例:
1到5月收入100,3到5月收入50,1到2月收入51
51 + 50 != 100,賬單不合理
題解:
差分約束的題
我們用sun[i]表示前i個月的總利潤
如果從第x月到第y月的利潤是z(z可正可負)
可以得到:sum[y] - sum[x-1] = z(可以理解為前綴和差值)
相當于我們會得到很多這樣的式子,然后去驗證是否合法
我們都知道差分約束是小于等于的關系,那這個題怎么做?
這樣就變成了差分約束的問題
連邊(y,x-1),邊權為-val
連邊(x-1,y),邊權為val
然后跑最短路去驗證是否有負環…(剩下的都是差分約束的過程了)
代碼:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+9; struct node{int v,w;node(int v=0, int w=0):v(v),w(w){}; }; vector<node>edge[maxn]; bool vis[maxn]; int dis[maxn]; int cnt[maxn]; int n,m; bool spfa(int now) {queue<int>q;dis[now]=0;q.push(now);vis[now]=1;while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=0;i<edge[u].size();i++){int v=edge[u][i].v;int w=edge[u][i].w;if(dis[v]>dis[u]+w){dis[v]=dis[u]+w;cnt[v]=cnt[u]+1;if(cnt[v]>=n+1)return 1;if(vis[v]==0){vis[v]=1;q.push(v);}}}}return 0; } void init() {for(int i=0;i<=n;i++)edge[i].clear();memset(dis,0x3f,sizeof(dis));memset(cnt,0,sizeof(cnt));memset(vis,0,sizeof(vis)); } int main() {int t;cin>>t;while(t--){cin>>n>>m;init();for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w;edge[v].push_back((node){u-1,-w});edge[u-1].push_back((node){v,w});}for(int i=1;i<=n;i++)edge[n+1].push_back((node){i,0});if(spfa(n+1))cout<<"false"<<endl;else cout<<"true"<<endl;}} /* 2 5 3 1 5 100 3 5 50 1 2 51 3 3 1 2 10 1 3 -5 3 3 -15*/總結
以上是生活随笔為你收集整理的P2294 [HNOI2005]狡猾的商人的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P4878 [USACO05DEC]La
- 下一篇: P1494 [国家集训队]小Z的袜子