您的位置:首页 > 其它

codeforces 319 div1 D(Matrices)

2015-09-14 11:12 225 查看
本题目的意思是给定了一个有向图,n个点,m条变,n<=150,每个边上还有一个d值代表已经经过了d条边这条边才能够走,那么求最少要经过多少条边才能从1出发走到n

解析:

用一个矩阵A(1,n) 代表当前该人走了固定步数可以到达的点,0代表不可以到达,1反之。

用一个B(n,n)代表当前的转移矩阵,即那些边是可以走的,那么把所有边按照d排序,那么在下一条边可以走之前,必须先由现在可达的状态至少再走差值步数,如果走了小于等于差值步数到达了n,那么只需在原来没走差值步的基础上枚举走几步可到达即可。

为了表示 “走了小于等于差值步数到达了n”初始B的n -> n为 1 代表可以在n这个地方逗留。

下面的模板用的是anta的,

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <list>
#include <cstdlib>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cassert>
#define ALL(a) a.begin(), a.end()
#define clr(a, x) memset(a, x, sizeof a)
#define fst first
#define snd second
#define pb push_back
#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rep1(i,x,y) for(int i=x;i<=y;i++)
#define rep(i,n) for(int i=0;i<(int)n;i++)
using namespace std;
const double eps = 1e-10;
typedef long long LL;
typedef long long ll;
typedef pair<int, int> pii;
const int oo =0x3f3f3f3f;

typedef bitset<160> BitSet;
struct Matrix {
    int wid;
    vector<BitSet> v, w;
    Matrix(): wid(0) {}
    Matrix(int n, int m): v(n, BitSet()), wid(m) { }
    inline int height() const { return (int)v.size(); }
    inline int width() const { return wid; }
    inline bool at(int i, int j) const { return v[i][j]; }
    static Matrix identity(int n) {
        Matrix A(n, n);
        rep(i, n) A.v[i][i] = 1;
        return A;
    }
    inline static Matrix identity(const Matrix& A) { return identity(A.height()); }
    vector<BitSet> trans() const {
        int n = height(), m = width();
        vector<BitSet> res(m, BitSet());
        rep(i, n) rep(j, m)
            res[j][i] = v[i][j];
        return res;
    }
    Matrix& operator*=(const Matrix& B) {
        int n = height(), m = B.width(), p = B.height();
        vector<BitSet> transB = B.trans();
        assert(p == width());
        w.assign(n, BitSet());
        rep(i, n) rep(j, m)
            w[i][j] = (v[i] & transB[j]).any();
        v.swap(w);
        return *this;
    }
    void show(){
       cout<<"--------------------\n";
       rep(i,height()){
            rep(j,width()) cout<<v[i][j]<<" ";
            cout<<endl;
       }
    }
};
Matrix operator^(const Matrix& t, ll k) {
    Matrix A = t, B = Matrix::identity(t);
    while(k) {
        if(k & 1) B *= A;
        A *= A;
        k >>= 1;
    }
    return B;
}
struct node{
   int u,v,d;
   node(int u=0,int v=0,int d=0):u(u),v(v),d(d){}
   bool operator<(const node& rhs)const{
      return d < rhs.d;
   }
};
int n,m;
vector<node> st;
int main()
{
   scanf("%d %d",&n,&m);
   rep(i,m){
      int x,y,z;
      scanf("%d %d %d",&x,&y,&z);
      x--; y--;
      st.push_back(node(x,y,z));
   }
   sort(st.begin(),st.end());
   Matrix A(n,n); A.v[n-1][n-1]=1;
   Matrix ans(1,n); ans.v[0][0]=1;
   int pred = 0 , res = -1;
   rep(i,st.size()+1){
      node te;
      if(i < st.size()) te = st[i];
      int k = (i == st.size() ? n : te.d - pred);
      Matrix cc = ans;
      ans*=A^k;
      if(ans.v[0][n-1]){
          for(int j=1;j<=n;j++){
              cc*=A;
              if(cc.v[0][n-1]){
                   res = pred + j;
                   break;
              }
          }
          break;
      }
      if(i == st.size()) break;
      A.v[te.u][te.v] = 1;
      pred = te.d;
   }

   if(res == -1) printf("Impossible\n");
   else printf("%d\n",res);
   return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: