P1260 工程规划
题目描述:
n个工程,每个工程都有一个起始时间,均是非负数,m个限制条件,每个限制条件形如
,问你能否找到一种解满足所以限制条件,如果有,则要使最早进行的那个任务和整个工程的起始时间相同,也就是说,T1,T2,…,Tn中至少有一个为0
思路:
板子题
化简后得到
,也就是从 j
到i
建立一个权值为b
的边然后建立一个超级源点0,跑最短路,输出的时候要先找出最小值,然后每个答案都要减去最小值再输出
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m;
int a, b, c;
int tot;
int head[MAX];
struct ran{
int to, nex, val;
}tr[MAX];
inline void add(int u, int v, int c){
tr[++tot].to = v;
tr[tot].val = c;
tr[tot].nex = head[u];
head[u] = tot;
}
int dis[MAX];
bool vis[MAX];
int cnt[MAX];
void SPFA(){
queue<int>q;
for(int i = 1; i <= n; ++i){
q.push(i);
vis[i] = 1;
dis[1] = 0;
}
while (!q.empty()) {
int u = q.front();q.pop();vis[u] = 0;
for(int i = head[u]; i; i = tr[i].nex){
int v = tr[i].to;
if(dis[v] > dis[u] + tr[i].val){
dis[v] = dis[u] + tr[i].val;
cnt[v] = cnt[u] + 1;
if(cnt[v] >= n){
cout << "NO SOLUTION\n";
return;
}
if(!vis[v]){
q.push(v);
vis[v] = 1;
}
}
}
}
int minx = inf;
for(int i = 1; i <= n; ++i)minx = min(minx, dis[i]);
for(int i = 1; i <= n; ++i)cout << dis[i] - minx << endl;
}
void work(){
cin >> n >> m;
while (m--) {
cin >> a >> b >> c;
add(b, a, c);
}
SPFA();
}
int main(){
io;
work();
return 0;
}