P2294 [HNOI2005] 狡猾的商人 五种做法
贪心
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e3+100;
int n,m;
struct NODE{
int l,r,val;
bool operator < (const NODE &h)const
{
if(l!=h.l) return l>h.l;
return r>h.r;
}
};
priority_queue<NODE> q;
signed main()
{
int T;
cin>>T;
while(T--)
{
while(q.size()) q.pop();
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int l,r,val;
cin>>l>>r>>val;
q.push({l,r,val});
}
bool sg=false;
auto tmp=q.top();
q.pop();
while(q.size())
{
auto tmp1=q.top();q.pop();
if(tmp.l==tmp1.l)
{
if(tmp.r==tmp1.r)
{
if(tmp.val!=tmp1.val)
{
sg=true;
break;
}
}
else
if(tmp.r<tmp1.r)
q.push({tmp.r+1,tmp1.r,tmp1.val-tmp.val});
}
tmp=tmp1;
}
if(sg) cout<<"false"<<endl;
else cout<<"true"<<endl;
}
return 0;
}
带权并查集
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=110;
int n,m;
int f[N],cha[N];
int find(int x)
{
if(x!=f[x])
{
int t=find(f[x]);
cha[x]+=cha[f[x]];
f[x]=t;
}
return f[x];
}
signed main()
{
int T;
cin>>T;
while(T--)
{
bool sg=false;
cin>>n>>m;
for(int i=0;i<=n;i++) f[i]=i,cha[i]=0;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
x--;
if(find(x)!=find(y))
{
cha[f[y]]=cha[x]-cha[y]-z;
f[f[y]]=f[x];
}
else
if(cha[x]-cha[y]!=z)
{
sg=true;
break;
}
}
if(sg) cout<<"false";
else cout<<"true";
cout<<endl;
}
return 0;
}
区间DP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=110;
int n,m;
int f[N][N];
signed main()
{
int T;
cin>>T;
while(T--)
{
memset(f,0,sizeof f);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
f[x][y]=z;
}
bool sg=true;
for(int i=2;i<=n;i++)
if(sg)//加速
for(int j=i-1;j>=1;j--)
if(sg)//加速*2
for(int k=j;k<i;k++)
if(f[j][k] && f[k+1][i])
{
if(f[j][i])
{
if(f[j][i]!=f[j][k]+f[k+1][i])
{
sg=false;
break;
}
}
else
f[j][i]=f[j][k]+f[k+1][i];
}
if(sg) cout<<"true";
else cout<<"false";
cout<<endl;
}
return 0;
}
高斯消元
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
double d[1100][110];
bool Guass()
{
int start=1;
for(int i=1;i<=n;i++)
{
int now=start;
while(now<=m && d[now][i]==0) now++;
if(now>m) continue;
for(int j=1;j<=n+1;j++)
swap(d[start][j],d[now][j]);
for(int j=start+1;j<=m;j++)
{
if(d[j][i]==0) continue;
double tmp=d[j][i]/d[start][i];
for(int k=i;k<=n+1;k++)
d[j][k]-=d[start][k]*tmp;
}
start++;
}
for(int i=1;i<=m;i++)
{
bool sg=true;
for(int j=1;j<=n;j++)
if(d[i][j]!=0)
sg=false;
if(d[i][n+1]!=0 && sg)
return false;
}
return true;
}
signed main()
{
int T;
cin>>T;
while(T--)
{
memset(d,0,sizeof d);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
for(int j=x;j<=y;j++) d[i][j]=1;
d[i][n+1]=z;//建立方程
}
if(Guass()) cout<<"true";
else cout<<"false";
cout<<endl;
}
return 0;
}
差分约束
#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define pa pair<int,int>
#define x first
#define y second
using namespace std;
const int N=120;
int n,m;
int dis[N];
int vis[N];
bool inq[N];
vector<pa> G[N];
signed main()
{
int T;
cin>>T;
while(T--)
{
bool sg=false;
cin>>n>>m;
for(int i=0;i<=n+1;i++) G[i].clear();
for(int i=1;i<=m;i++)
{
int u,v,z;
cin>>u>>v>>z;
G[u-1].pb({v,z});
G[v].pb({u-1,-z});
}
for(int i=0;i<=n;i++)
G[n+1].pb({i,0});
queue<int> q;
q.push(n+1);
memset(dis,0xcf,sizeof dis);
memset(vis,0,sizeof vis);
memset(inq,0,sizeof inq);
dis[n+1]=0;
while(q.size())
{
if(sg) break;
int t=q.front();
q.pop();
inq[t]=0;
for(auto i:G[t])
{
if(dis[i.x]<dis[t]+i.y)
{
dis[i.x]=dis[t]+i.y;
if(!inq[i.x])
{
vis[i.x]++;
if(vis[i.x]>n)
{
sg=true;
break;
}
inq[i.x]=true;
q.push(i.x);
}
}
}
}
if(sg) cout<<"false";
else cout<<"true";
cout<<endl;
}
return 0;
}