• [P3074 | USACO13FEB] Milk Scheduling | SPFA最长路 | 超级源点 + 超级汇点


    题目描述

    Farmer John’s N cows (1 <= N <= 10,000) are conveniently numbered 1…N.
    Each cow i takes T(i) units of time to milk. Unfortunately, some cows must be milked before others, owing to the layout of FJ’s barn. If cow A must be milked before cow B, then FJ needs to completely finish milking A before he can start milking B.

    In order to milk his cows as quickly as possible, FJ has hired a large number of farmhands to help with the task – enough to milk any number of cows at the same time. However, even though cows can be milked at the same time, there is a limit to how quickly the entire process can proceed due to the constraints requiring certain cows to be milked before others. Please help FJ compute the minimum total time the milking process must take.

    输入

    • Line 1: Two space-separated integers: N (the number of cows) and M(the number of milking constraints; 1 <= M <= 50,000).

    • Lines 2…1+N: Line i+1 contains the value of T(i) (1 <= T(i) <= 100,000).

    • Lines 2+N…1+N+M: Each line contains two space-separated integers A and B, indicating that cow A must be fully milked before one can start milking cow B. These constraints will never form a cycle, so a solution is always possible.

    输出

    • Line 1: The minimum amount of time required to milk all cows.

    样例输入

    3 1
    10
    5
    6
    3 2
    

    样例输出

    11
    

    提示

    INPUT DETAILS:
    There are 3 cows. The time required to milk each cow is 10, 5, and 6,respectively. Cow 3 must be fully milked before we can start milking cow 2.

    OUTPUT DETAILS:
    Cows 1 and 3 can initially be milked at the same time. When cow 3 is finished with milking, cow 2 can then begin. All cows are finished milking after 11 units of time have elapsed.

    题意:
    一共有n头奶牛,每头奶牛挤奶都会消耗一定的时间 t i t_i ti
    然后有 m m m个关系, u − v u-v uv,其含义是 u u u必须在 v v v之前挤奶,而且有足够的人手多线程挤奶,问为这 n n n头奶牛挤完奶一共需要消耗多长时间

    思路:
    首先可以确定这m个关系中,不会出现环的情况,所以说可以考虑用 s p f a spfa spfa来处理这道题目,怎么来确定最后被挤奶的奶牛呢?
    因为 m m m个关系可以看作是有向边,所以最后被挤奶的奶牛一定是出度为0的,但出度为0的点可能并不唯一
    怎样来确定从那一头牛开始?
    类似的我们可以知道一定是从入读为0的点开始,入度为0的点也可能并不唯一

    所以我们可以建立一个超级源点 0 0 0与所有入度为0的点相连,然后让所有出度为0的点与超级汇点 n + 1 n+1 n+1相连,所以说最终的答案就是从超级源点走到超级汇点的最长路径
    因为需要从0转移到其他节点,所以说可以先给0号节点设置一个点权1,最终减去即可

    ac_code:

    #define Clear(x,val) memset(x,val,sizeof x)
    int in[maxn],out[maxn];
    typedef pair<ll,int> PII;
    int n,m;
    vector<int>gra[maxn];
    ll a[maxn];
    ll dis[maxn];
    bool vis[maxn];
    int cnt,head[maxn];
    void init() {
    	cnt = 0;
    	Clear(head,-1);
    }
    struct node {
    	int v,nex;
    } e[maxn];
    void add(int u,int v) {
    	e[cnt].v = v;
    	e[cnt].nex = head[u];
    	head[u] = cnt ++;
    }///ac 
    void spfa() {
    	dis[0] = 0;
    	vis[0] = 1;
    //	queue<PII> que;
    	priority_queue<PII,vector<PII>,greater<PII> > que;
    	que.push({0,0});
    	while(que.size()) {
    		PII cur = que.top();
    		que.pop();
    		int u = cur.second;
    		vis[u] = false;
    		for(int i=head[u]; ~i; i=e[i].nex) {
    			int to = e[i].v;
    			if(dis[to] < dis[u] + a[u]) {
    				dis[to] = dis[u] + a[u];
    				if(!vis[to]) {
    					vis[to] = true;
    					que.push({dis[to],to});
    				}
    			}
    		}
    	}
    }
    int main() {
    	n = read,m = read;
    	init();
    	a[0] = 1;
    	Clear(dis,0);
    	Clear(vis,0);
    	for(int i=1; i<=n; i++)  a[i] = read;
    	for(int i=1; i<=m; i++) {
    		int u = read,v = read;
    		gra[u].push_back(v);
    		add(u,v);
    		in[v] ++;
    		out[u] ++;
    	}
    	for(int i=1; i<=n; i++) {
    		if(!in[i]) add(0,i);
    		if(!out[i]) add(i,n+1);
    	}
    	spfa();
    	cout << dis[n + 1] - 1 << endl;
    	return 0;
    }
    
  • 相关阅读:
    【作业3】应用分支与循环结构解决问题
    四、预习检查:填空,并注释"每空"填充的依据
    三、预习检查:选择正确答案,并简要说明为什么?
    作业 6 结构体
    实验 10 指针2 (2)为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文。变换规则是:小写字母z变换成为a,其它字符变换成为该字符ASCII码顺序后1位的字符,比如o变换为p。
    实验 9 指针1 输入一行字符,要求用自定义的函数void f(char *line)统计和输出字符串中数字字符、英文字符和其他字符的个数
    作业 5 指针应用1
    实验9指针1
    实验 8 数组2 输出一张九九乘法口诀表。要求必须将乘积放入一个二维数组中,再输出该数组
    作业 4 函数应用 输出80到120之间的满足给定条件的所有整数,条件为构成该整数的每位数字都相同
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459783.html
Copyright © 2020-2023  润新知