bzoj3389:[Usaco2004 Dec]Cleaning Shifts安排值班
生活随笔
收集整理的這篇文章主要介紹了
bzoj3389:[Usaco2004 Dec]Cleaning Shifts安排值班
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
思路:可以貪心,也可以最短路。
貪心寫法:因為在保證合法的前提下,我們選擇的區間一定要右端點盡量靠后才行,于是我們每次就選擇一個合法的并且右端點最靠后的區間就好了(如果沒有合法的輸出-1即可)。時間復雜度O(nlogn)(排序是nlogn的,貪心是O(n)的)。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 25005int n,t,ans; int last[1000005];struct node{int l,r;bool operator <(const node &a)const{return l<a.l||(l==a.l&&r<a.r);} }a[maxn];inline int read(){int x=0;char ch=getchar();for (;ch<'0'||ch>'9';ch=getchar());for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x; }int main(){n=read(),t=read();for (int i=1;i<=n;i++) a[i].l=read(),a[i].r=read();sort(a+1,a+n+1);int cnt=0;for (int i=1;i<=n;i++)if (a[i].l!=a[i+1].l) a[++cnt]=a[i];n=cnt;int now=0;for (int i=1;i<=n;i++){int x=0;bool flag=0;while (a[i].l<=now+1&&i<=n) x=max(x,a[i].r),i++,flag=1;if (!flag){ans=-1;break;}if (x>now) now=x,ans++;i--;}if (now!=t) ans=-1;printf("%d\n",ans);return 0; }最短路寫法:區間[l,r]表示可以從l-1走到r,那么我們就把l-1連一條權值為1的邊到r即可,然后又因為區間可以有交集,所以還需要將i向i-1連一條權值為0的邊,然后以0為起點跑最短路即可(以0為起點是因為是l-1連向r)。時間復雜度O(TlogT)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define maxn 1000005 #define inf 1e9int n,t,tot; int now[maxn],pre[maxn*2],son[maxn*2],val[maxn*2],dis[maxn]; bool vis[maxn];inline int read(){int x=0;char ch=getchar();for (;ch<'0'||ch>'9';ch=getchar());for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x; }void add(int a,int b,int c){son[++tot]=b;pre[tot]=now[a];now[a]=tot;val[tot]=c; }void link(int a,int b,int c){add(a,b,c); }struct node{int id,val;node(){}node(int a,int b){id=a,val=b;}bool operator <(const node &a)const{return val>a.val;} }; priority_queue<node> heap;void dijkstra(int x){memset(dis,127,sizeof(dis)),dis[x]=0;heap.push(node(x,0));while (!heap.empty()){node x=heap.top();heap.pop();int id=x.id,v=x.val;if (vis[id]) continue;vis[id]=1;for (int p=now[id];p;p=pre[p])if (dis[son[p]]>v+val[p]) heap.push(node(son[p],dis[son[p]]=v+val[p]));} }int main(){n=read(),t=read();for (int i=1,a,b;i<=n;i++) a=read(),b=read(),link(a-1,b,1);for (int i=1;i<=t;i++) link(i,i-1,0);dijkstra(0);if (dis[t]>1e9) puts("-1");else printf("%d\n",dis[t]);return 0; }轉載于:https://www.cnblogs.com/DUXT/p/6044799.html
總結
以上是生活随笔為你收集整理的bzoj3389:[Usaco2004 Dec]Cleaning Shifts安排值班的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ie 7 beta 2出来了
- 下一篇: Docker镜像下载加速的两种方法